zoukankan      html  css  js  c++  java
  • Codeforces 279D The Minimum Number of Variables 状压dp

    The Minimum Number of Variables

    我们定义dp[ i ][ mask ]表示是否存在 处理完前 i 个a, b中存者 a存在的状态是mask 的情况。

    然后用sosdp处理出,状态为state的a, 能组成的数字, 然后转移就好啦。

    #include<bits/stdc++.h>
    #define LL long long
    #define LD long double
    #define ull unsigned long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ALL(x) (x).begin(), (x).end()
    #define fio ios::sync_with_stdio(false); cin.tie(0);
    
    using namespace std;
    
    const int N = 1000 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    const double PI = acos(-1);
    
    template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;}
    template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;}
    template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;}
    template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;}
    
    int n;
    int a[N];
    
    int cnt[1 << 23];
    int sos[1 << 23];
    bool dp[23][1 << 23];
    
    int main() {
        scanf("%d", &n);
        for(int i = 1; i < (1 << n); i++)
            cnt[i] = cnt[i - (i & - i)] + 1;
        for(int i = 0; i < n; i++) scanf("%d", &a[i]);
        for(int i = 0; i < n; i++) {
            for(int j = i; j < n; j++) {
                 int ret = a[i] + a[j];
                 for(int k = 0; k < n; k++) {
                    if(ret == a[k])
                        sos[(1 << i) | (1 << j)] |= 1 << k;
                 }
            }
        }
        for(int i = 0; i < n; i++)
            for(int mask = 0; mask < (1 << n); mask++)
                if(mask >> i & 1) sos[mask] |= sos[mask ^ (1 << i)];
    
        dp[0][1] = 1;
        for(int i = 0; i < n - 1; i++) {
            for(int mask = 0; mask < (1 << n); mask++) {
                if(!dp[i][mask]) continue;
                if(sos[mask] >> (i + 1) & 1) {
                    dp[i + 1][mask | (1 << (i + 1))] = true;
                    for(int j = 0; j <= i; j++) {
                        if(mask >> j & 1) {
                            dp[i + 1][(mask ^ (1 << j)) | (1 << (i + 1))] = true;
                        }
                    }
                }
            }
        }
        int ans = inf;
        for(int i = 1; i < (1 << n); i++)
            if(dp[n - 1][i]) chkmin(ans, cnt[i]);
        if(ans == inf) ans = -1;
        printf("%d
    ", ans);
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    oracle 导入数据时提示只有 DBA 才能导入由其他 DBA 导出的文件
    oracle 常用语句
    android udp 无法收到数据 (模拟器中)
    android DatagramSocket send 发送数据出错
    AtCoder ABC 128E Roadwork
    AtCoder ABC 128D equeue
    AtCoder ABC 127F Absolute Minima
    AtCoder ABC 127E Cell Distance
    CodeForces 1166E The LCMs Must be Large
    CodeForces 1166D Cute Sequences
  • 原文地址:https://www.cnblogs.com/CJLHY/p/10755757.html
Copyright © 2011-2022 走看看