• To My Girlfriend (DP)


      题意:求选中若干个数,满足和为S,且不能选中下表i, j 和选中k, l的情况总数量。

      思路:DP[i][j][k][l] i:前i个和为j,选中k个和不选中l个的情况数量,那么我们的转换应该是在必选/必不选中扩展,还有就是可以都不用,和最多不超过2个选和不选。然后由于i、j之间可以互换位置,k、l之间也可以互换位置所以结果需要乘以4.

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    
    const int maxn = 1e3 + 7;
    const int maxm = 1e6 + 7;
    const int mod  = 1e9 + 7;
    
    unsigned dp[maxn][maxn][3][3];
    int a[maxn];
    
    int main(){
        int T, n, s;scanf("%d", &T);
        while(T --) {
            scanf("%d%d", &n, &s);
            for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
            memset(dp, 0, sizeof(dp));
            dp[1][a[1]][0][0] = 1;
            dp[1][a[1]][1][0] = 1;
            dp[1][0][0][0] = 1;
            dp[1][0][0][1] = 1;
            for(int i = 2; i <= n; i ++){
                for(int j = 0; j <= s; j ++) {
                    int tmp = j + a[i];
                    if(tmp <= s)
                    for(int k = 0; k <= 2; k ++){
                        dp[i][tmp][0][k] = (dp[i][tmp][0][k] + dp[i - 1][j][0][k]) % mod;
                        dp[i][tmp][1][k] = (dp[i][tmp][1][k] + dp[i - 1][j][0][k]) % mod;
                        dp[i][tmp][1][k] = (dp[i][tmp][1][k] + dp[i - 1][j][1][k]) % mod;
                        dp[i][tmp][2][k] = (dp[i][tmp][2][k] + dp[i - 1][j][1][k]) % mod;
                        dp[i][tmp][2][k] = (dp[i][tmp][2][k] + dp[i - 1][j][2][k]) % mod;
                    }
                    for(int k = 0; k <= 2; k ++){
                        dp[i][j][k][0] = (dp[i][j][k][0] + dp[i - 1][j][k][0]) % mod;
                        dp[i][j][k][1] = (dp[i][j][k][1] + dp[i - 1][j][k][0]) % mod;
                        dp[i][j][k][1] = (dp[i][j][k][1] + dp[i - 1][j][k][1]) % mod;
                        dp[i][j][k][2] = (dp[i][j][k][2] + dp[i - 1][j][k][1]) % mod;
                        dp[i][j][k][2] = (dp[i][j][k][2] + dp[i - 1][j][k][2]) % mod;
                    }
                }
            }
            long long ans = 0;
            for(int i = 0; i <= s; i ++)
                ans = (ans + dp[n][i][2][2]) % mod;
            printf("%lld
    ", ans * 4LL % mod);
    
        }
        return 0;
    }
    more crazy more get!
  • 相关阅读:
    高危预警|RDP漏洞或引发大规模蠕虫爆发,用户可用阿里云免费检测服务自检,建议尽快修复
    高危预警| SQL数据库成主要攻击对象,或引发新一轮大规模勒索
    dp练习(7)—— 最小和
    dp练习(6)——搬运礼物
    dp练习(5)——最长严格上升子序列
    dp练习(4)——过河卒
    dp练习(3)——棋盘问题
    dp练习(2)——老鼠的旅行
    dp练习(1)——马走日字
    埃氏筛法——标记质数
  • 原文地址:https://www.cnblogs.com/wethura/p/9932852.html
Copyright © 2020-2023  润新知