Codeforces Round #171 (Div. 2)

来源:互联网 发布:epsonl455清零软件 编辑:程序博客网 时间:2024/05/21 22:28

转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove


A:模拟,然后判断

B:枚举起点,然后二分最远的。或者维护两个指针

C:预处理出up[i],down[i]
      up[i]表示从i开始,非递减到最远的位置
      down[i]表示从i往前,非递减到最远的位置
     那么对于某个区间[l,r]只要up[i]<down[i],说明中间还有段区间,否则为YES

D:状态压缩DP。
      对于某一个状态,最高位上的1,说明当前需要用低位相加凑出来。
      所有低位上为1表示当前已经有这个数,否则没有
      递归,记忆化DP,路径上所有状态包含1个数的最大值便是解,找到最优解就行了
int n;int a[23];int dp[1<<23];int s[1<<23];int dfs(int state){    if(dp[state]<inf)        return dp[state];    int ans=inf;    for(int i=n-1;i>=0;i--){        if(state&(1<<i)){            int pre=state^(1<<i);            for(int j=0;j<i;j++)                for(int k=0;k<i;k++){                    if(a[j]+a[k]==a[i]){                        int cur=pre;                        cut=cur|(1<<j)|(1<<k)|(1<<(i-1));                        ans=min(ans,max(dfs(cur),s[cur]));                    }                }            break;        }    }    return dp[state]=ans;}int main(){    for(int i=1;i<(1<<23);i++)        s[i]=s[i>>1]+(i&1);    cin>>n;    for(int i=0;i<n;i++)        cin>>a[i];    if(n==1){        cout<<1<<endl;        return 0;    }    mem(dp,0x3f);    dp[1]=0;    dp[0]=0;    dfs(1<<(n-1));    cout<<(dp[1<<(n-1)]>=inf?-1:dp[1<<(n-1)])<<endl;    return 0;}

E:DP,有两种情况
    某位是1,在高位为+,然后在低位为-
   所以dp[0][i]表示当前位为+,dp[1][i]表示当前位处于第二种情况

显然的骗访问,呵呵~~~
原创粉丝点击