zoukankan      html  css  js  c++  java
  • BZOJ 2064: * 状压动归

    最多的操作次数是 $n+m-1$ (相当于把第一个暴力合并,再暴力拆成第二个).
    如果第一个序列的一个子序列和第二个区间的子序列相等,那么总次数就可以减 $2$.
    将第二个序列所有数取反,直接求解有多少个子序列的和为 $0$ 即可
    $ans=n+m-dp[1<<(n+m)-1]$
    具体:

    • $dp[i]=max(dp[i],dp[i xor (j<<1)])$
    • $dp[i]=dp[i]+1, sum[i]=0$
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn=22;
    int dp[1<<maxn],num[maxn],sum[1<<maxn];
    int main()
    {
        freopen("in.txt","r",stdin);
        int n,m,N;
        scanf("%d",&n);
        for(int i=1;i<=n;++i)scanf("%d",&num[i]);
        scanf("%d",&m);
        for(int i=n+1;i<=n+m;++i)
        {
            scanf("%d",&num[i]);
            num[i]=-num[i];
        }
        N=n+m;
        for(int i=1;i<(1<<N);++i)
        {
            sum[i]=0;
            for(int j=1;j<=N;++j)
            {
                if(i&(1<<(j-1)) )
                {
                    sum[i]+=num[j];
                    dp[i]=max(dp[i],dp[i^(1<<(j-1))]);
                }
            }
            if(sum[i]==0)++dp[i];
        }
        printf("%d",n+m-2*dp[(1<<N)-1]);
        return 0;
    }
    

      

  • 相关阅读:
    10多媒体
    胡凡-01
    概念
    算法
    07Axios
    05VueCli
    04Vue.js路由系统
    03生命周期
    《穷人思维》学习感悟
    《基金》学习感悟之二
  • 原文地址:https://www.cnblogs.com/guangheli/p/9845213.html
Copyright © 2011-2022 走看看