Codeforces Round #384 (Div. 2) //复习状压... 罚时爆炸 BOOM

不想欠题了..... 多打打CF才知道自己智商不足啊...

A. Vladik and flights

给你一个01串  相同之间随便飞 没有费用 不同的飞需要费用为  abs i-j

真是题意杀啊,,,实际上我们只考虑01转换的代价一定为1如果目的地和起点相同  费用为0

不相同  肯定为1  因为0旁边必然有1

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <string.h>
#include <cctype>
#include <climits>
using namespace std;
typedef long long ll;
template <class T>
inline bool r(T &ret)
{
    char c;
    int sgn;
    if (c = getchar(), c == EOF)
    {
        return 0; //EOF
    }
    while (c != ‘-‘ && (c < ‘0‘ || c > ‘9‘))
    {
        c = getchar();
    }
    sgn = (c == ‘-‘) ? -1 : 1;
    ret = (c == ‘-‘) ? 0 : (c - ‘0‘);
    while (c = getchar(), c >= ‘0‘ && c <= ‘9‘)
    {
        ret = ret * 10 + (c - ‘0‘);
    }
    ret *= sgn;
    return 1;
}
const int N = 1e5+10;
char ch[N];
int main()
{
    int n;
    r(n);
    int x,y;
    r(x),r(y);
    scanf("%s",ch+1);
    if(ch[x]==ch[y])
    {
        printf("0\n");
    }
    else{
        printf("1\n");
    }
    return 0;
}

zz

B. Chloe and the sequence

给一个n,然后按照 1  121 1213121 的第n个串

那么肯定是二分n次必得....  赛场拿python写的   (L+R)没加括号T1

n,k = map(int, input().split())
def calc(k):
    L = 0
    R = 2**n
    M = L+R//2
    ans = 0
    while(k!=M):
        if(k>M):
            L = M
        else:
            R = M
        M = (L+R)//2
        ans+=1
    print(n-ans)
calc(k)

Py

C. Vladik and fractions

问2/n能不能由1/a+1/b+1/c(a,b,c互不相同) 太粗心,没看到互不相同 wa1 没特判1 被hack 1

手推 a = n b = n+1 c = n*(n+1)

n=1分不出的

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <string.h>
#include <cctype>
#include <climits>
using namespace std;
typedef long long ll;
template <class T>
inline bool r(T &ret)
{
    char c;
    int sgn;
    if (c = getchar(), c == EOF)
    {
        return 0; //EOF
    }
    while (c != ‘-‘ && (c < ‘0‘ || c > ‘9‘))
    {
        c = getchar();
    }
    sgn = (c == ‘-‘) ? -1 : 1;
    ret = (c == ‘-‘) ? 0 : (c - ‘0‘);
    while (c = getchar(), c >= ‘0‘ && c <= ‘9‘)
    {
        ret = ret * 10 + (c - ‘0‘);
    }
    ret *= sgn;
    return 1;
}

int main()
{
    int n;
    r(n);
    if(n==1) printf("-1");
    else printf("%d %d %d\n",n,n+1,n*(n+1));
    return 0;
}

AC

D.Chloe and pleasant prizes

MK 一下

E. Vladik and cards

题意给以一个1-8组成的串  选出一个子串(在原串中可以不连续)  选出来的串 每个数相同的一定相邻  而且 每种数的个数相差不超过1

比赛时只想到DFS的解,后来证实是错的

后来看别人的代码一脸蒙=。=... 后来一神说了两个数组的作用才明白...就这样   参考claris的写法

而且....

这样也写了好久  而且还少更新状态   长度可以为0......

#include<cstdio>
#include<cstring>
void Min(int &a,int b) {if(a>b) a=b;}
void Max(int &a,int b) {if(a<b) a=b;}
const int maxn = 1010;
int cnt[10];
int g[maxn][maxn][10];//i j k
int dp[256][10];//i 选择方案  j 代表  长度的集合个数   长度最多n/8+1
int val[maxn];
int n;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&val[i]),val[i]--;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n+5;j++)
            for(int k=0;k<=8;k++) g[i][j][k] = maxn;
        memset(cnt,0,sizeof(cnt));
        for(int j=i;j<=n;j++)
            g[i][++cnt[val[j]]][val[j]] = j;
    }
    int ans = 0;
    for(int i=0;i*8<=n;i++)//长度
    {
        for(int j=0;j<256;j++)
            for(int k=0;k<=8;k++)
                dp[j][k] = maxn;
        dp[0][0] = 1; //从1开始
        for(int j=0;j<256;j++)//选择方案
        {
            for(int k=0;k<=8;k++)//
            {
                if(dp[j][k]>n)continue;
                for(int l=0;l<8;l++)
                {
                    if((1<<l)&j) continue;
                    Min(dp[j|(1<<l)][k],g[dp[j][k]][i][l]+1);
                    Min(dp[j|(1<<l)][k+1],g[dp[j][k]][i+1][l]+1);
                }
            }
        }
        for(int j=0;j<=8;j++) if(dp[255][j]<n+2){
            Max(ans,j+8*i);
        }
    }
    printf("%d\n",ans);
    return 0;
} 

状压DP

时间: 2024-08-26 10:51:40

Codeforces Round #384 (Div. 2) //复习状压... 罚时爆炸 BOOM的相关文章

Codeforces Round #384 (Div. 2)

A: 水题; B: 水题; C: n,n+1,n*(n+1) D: dfs,在这棵树上找到两个不相交的子树,使的这两棵子树上所有节点的权值和最大; dfs的过程中更新答案就好了; E: 二分+状压dp, 二分答案,然后在check的时候,dp[i][j]表示前i个的状态为j时的最长长度,对于每个i,a[i]要么不选,要么作为最后一个向前找len,或者len+1来转移, 感觉跟上海那个D有点相似来着;

Codeforces Round #384 (Div. 2) B. Chloe and the sequence(规律题)

传送门 Description Chloe, the same as Vladik, is a competitive programmer. She didn't have any problems to get to the olympiad like Vladik, but she was confused by the task proposed on the olympiad. Let's consider the following algorithm of generating a

Codeforces Round #261 (Div. 2) D 树状数组应用

看着题意:[1,i]中等于a[i]的个数要大于[,jn]中等于a[j]的个数 且i<j,求有多少对这样的(i,j)  ,i<j但是 i前面的合法个数 要大于j后面的 看起来很像逆序数的样子,所以很容易往树状数组想去,但是处理就看个人了,像我比赛的时候就处理得非常的麻烦,虽做出了但是花时间也多,经过杰哥的教育,其实正着塞进树状数组 反着来找就可以了,灰常的简单清晰明了,贴一发纪念我的搓比 int n; int aa[1000000 + 55]; int bb[1000000 + 55]; int

Codeforces Round #261 (Div. 2) D. Pashmak and Parmida&#39;s problem (树状数组求逆序数 变形)

题目链接 题意: 给出一些数a[n],求(i, j), i<j 的数量,使得:f(1, i, a[i]) > f(j, n, a[j]) . f(lhs, rhs, x) 指在 { [lhs, rhs]范围中,a[k]的值=x } 的数量. 1.  f(1, i, a[i]) 就是指a[i]前面包括a[i]的数中,有几个值=a[i]. 2.  f(j, n, a[j]) 就是指a[j]后面包括a[j]的数中有几个值=a[j]. 虽然a[x]范围不小,但是n的范围是1000,不是很大,所以我们可

Codeforces Round #261 (Div. 2) D. Pashmak and Parmida&#39;s problem (树状数组)

D. Pashmak and Parmida's problem time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard output Parmida is a clever girl and she wants to participate in Olympiads this year. Of course she wants her partn

Codeforces Round 261 Div.2 D Pashmak and Parmida&#39;s problem --树状数组

题意:给出数组A,定义f(l,r,x)为A[]的下标l到r之间,等于x的元素数.i和j符合f(1,i,a[i])>f(j,n,a[j]),求有多少对这样的(i,j). 解法:分别从左到右,由右到左预处理到某个下标为止有多少个数等于该下标,用map维护. 然后树状数组更新每个f(j,n,a[j]),预处理完毕,接下来,从左往右扫过去,每次从树状数组中删去a[i],因为i != j,i不能用作后面的统计,然后统计getsum(inc[a[i]]-1), (inc表示从左到右),即查询比此时的a[i]

Codeforces Round #424 (Div. 2) D 思维 E set应用,树状数组

Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) D. Office Keys 题意:一条直线上,有个办公室坐标 p,有 n个人在a[i],有 k把钥匙在b[i],每个人必须拿到一把钥匙,然后到办公室.问怎么安排花的时间最短. tags:还是不懂套路啊..其实多画两下图就能够感觉出来,2333 关键是要看出来,n个人拿的 n把钥匙应该是连续的. 然后,就是瞎暴力.. #include<bits/stdc++.h> usi

Codeforces Round #259 (Div. 2)-D. Little Pony and Harmony Chest

题目范围给的很小,所以有状压的方向. 我们是构造出一个数列,且数列中每两个数的最大公约数为1; 给的A[I]<=30,这是一个突破点. 可以发现B[I]中的数不会很大,要不然就不满足,所以B[I]<=60左右.构造DP方程DP[I][J]=MIN(DP[I][J],DP[I][J^C[K]]+abs(a[i]-k)); K为我们假设把这个数填进数组中的数.同时开相同空间记录位置,方便输出结果.. #include<iostream> #include<stdio.h>

Codeforces Round #243 (Div. 1)

---恢复内容开始--- A 枚举l,r 1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 us