zoukankan      html  css  js  c++  java
  • HDU

    HDU - 5800

    第一感觉就是算每个 <= s的子集的贡献,

    如果一个自己长度为k, 那么贡献为 C(k, 2) * C(n - k, 2), 

    然后就需要一个n3的dp去记录长度以及重量和。

    感觉以前没有写过这个dp。。。

    其实我们不需要记录长度, 我们只需要记录已经选了几个必选的, 和选了几个一定不选的就可以了。

    dp[ i ][ j ][ u ][ v ], 表示处理了前 i 个物品, 价值和为 j, 一定选的选了 u 个, 一定不选的选了 v 个的方案数,

    这样就解决了最后需要乘以一个组合数的问题。

    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #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 = (int)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;}
    
    //mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    
    int n, s, a[N];
    int dp[2][N][3][3];
    int (*f)[3][3] = dp[0];
    int (*g)[3][3] = dp[1];
    
    void recover() {
        for(int i = 0; i <= s; i++) {
            for(int j = 0; j < 3; j++) {
                for(int k = 0; k < 3; k++) {
                    f[i][j][k] = 0;
                }
            }
        }
    }
    
    int main() {
        int T; scanf("%d", &T);
        while(T--) {
            scanf("%d%d", &n, &s);
            for(int i = 1; i <= n; i++) {
                scanf("%d", &a[i]);
            }
            recover();
            f[0][0][0] = 1;
            for(int o = 1; o <= n; o++) {
                swap(f, g);
                recover();
                for(int i = 0; i <= s; i++) {
                    // 0
                    for(int j = 0; j < 3; j++) {
                        for(int k = 0; k < 3; k++) {
                            add(f[i][j][k], g[i][j][k]);
                            if(k < 2) add(f[i][j][k + 1], g[i][j][k]);
                        }
                    }
    
                    // 1
                    if(i + a[o] <= s) {
                        for(int j = 0; j < 3; j++) {
                            for(int k = 0; k < 3; k++) {
                                add(f[i + a[o]][j][k], g[i][j][k]);
                                if(j < 2) add(f[i + a[o]][j + 1][k], g[i][j][k]);
                            }
                        }
                    }
                }
            }
            int ans = 0;
            for(int i = 0; i <= s; i++) {
                add(ans, f[i][2][2]);
            }
            printf("%d
    ", 1LL * ans * 4 % mod);
        }
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    HTTP断点续传 规格严格
    Java Shutdown 规格严格
    linux 命令源码 规格严格
    JTable调整列宽 规格严格
    linux 多CPU 规格严格
    Hello can not find git path 规格严格
    Kill 规格严格
    拜拜牛人 规格严格
    Swing 规格严格
    Debugging hangs in JVM (on AIX but methodology applicable to other platforms) 规格严格
  • 原文地址:https://www.cnblogs.com/CJLHY/p/11469028.html
Copyright © 2011-2022 走看看