• A. Writing Code 完全背包


    http://codeforces.com/contest/543/problem/A

    一开始这题用了多重背包做,结果有后效性。

    就是如果6,这样拆分成

    1 + 2 + 3的,那么能产生3的就有两种情况了(同一种物品,两种情况,所以有了后效性)

    分别是1 + 2 = 3和0 + 3 = 3

    以前的多重背包只需要输出那些最优解,所以这个后效性可以忽略,但是现在是输出方案种类,所以不能忽视。

    一开始的时候还以为他只能写b / per_bug个,因为最多b个bug,每个程序员写per_bug个。那么就是b / per_bug行。

    所以觉得是多重背包。但是不是,第一,这里没限制它写多少行,确实是最多b / per_bug行,但是如果多了几行,也就是超过了背包容量,这其实和无限使用时一个意思的。

    多重背包的都是最多能用c个,而且用了c + 1 个的话,还是没超过背包容量的,这才是多重背包。。

    那么这么想,任何一个programmer,都可以写0...m行。

    因为它能写m行,而这个m已经是背包容量的最大值了。所以就相当于完全背包了。

    如果再选多个容量就超过了背包容量,那不会叠加上来的。这是完全背包的思想吧

    那么设dp[m][b]表示前i个程序员,一共写了m行,有b个bug的情况。

    对于每个程序员,都可以写0...m行,dp[m][b] += dp[m - 1][b - cost];

    从自己写的m - 1行递推上来,就相当于写了m行了。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <assert.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #include <conio.h>
    const int maxn = 500 + 20;
    struct node {
        int hang;
        int bug;
        node(int hh, int bb) : hang(hh), bug(bb) {}
        node() {}
    }a[maxn];
    int w[maxn];
    int val[maxn];
    int dp[maxn][maxn];
    void work() {
        int n, m, b, MOD;
        scanf("%d%d%d%d", &n, &m, &b, &MOD);
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &w[i]);
        }
        dp[0][0] = 1;
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= m; ++j) {
    //            if (j * w[i] > b) break;
                for (int k = w[i]; k <= b; ++k) {
                    dp[j][k] += dp[j - 1][k - w[i]];
                    if (dp[j][k] >= MOD) dp[j][k] %= MOD;
                }
            }
        }
        int ans = 0;
        for (int i = 0; i <= b; ++i) {
            ans += dp[m][i];
            if (ans >= MOD) ans %= MOD;
        }
        printf("%d
    ", ans);
    }
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        work();
        return 0;
    }
  • 相关阅读:
    大牛都是这样写测试用例的,你get到了嘛?
    炸!分享美团面试关于selenium的面试题
    功能测试如何快速转向自动化测试?
    接口测试之深入理解HTTPS
    Linux之用户和权限
    Hash函数及其应用
    用代码控制网络断开与重连
    Windows Azure初体验
    JS跨域知识整理
    最大子序列和问题
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6242737.html
Copyright © 2020-2023  润新知