HDU 5000 Clone (多重背包)

来源:互联网 发布:帝国cms整站模板 编辑:程序博客网 时间:2024/05/17 06:23

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5000

题意:

有一个人他可以克隆自己, 但克隆出来的自己并不完全一样。对于每两个自己,A和B,他会看n个属性,如果B的每一项属性都比不过A,那么B就不能存在。

每一个属性的评分范围为0-t [ i ],问最多能存在多少个他自己。

思路:

对于可以同时存在的两个人,假如有3个属性

a1 + b1 + c1 = a2 + b2 + c2

如果 a1 > a2 则 b1 < b2 和 c1 < c2 必满足一项,

即 只要各个属性之和相同且A有一个属性大于B,则B一定有一个大于A

问题转化为,在每个属性中各取一个值使和为一定值的最大方案数,易得和应取sum=(t1 + t2 + ... + tn)/ 2 (贪心)

在每个属性中各取一个值使和等于sum的方案数,每个属性看成一种物品,取得值代表取这种物品多少个,每个物品价值为1

代码:

#include <stdio.h>#include <string.h>#include <math.h>#include <algorithm>#define MOD 1000000007#define INF 0x7fffffffusing namespace std;typedef long long ll;int t[2005], dp[2005][2005];int main(){    #ifdef LOCAL    freopen("dpdata.txt", "r", stdin);    #endif    int cas, n, sum;    scanf("%d", &cas);    while(cas--)    {        scanf("%d", &n);        sum = 0;        for(int i = 0; i < n; i++)        {            scanf("%d", &t[i]);            sum += t[i];        }        memset(dp, 0, sizeof(dp));        for(int i = 0; i <= t[0]; i++)            dp[0][i] = 1;        sum /= 2;        for(int i = 1; i < n; i++)        {            for(int j = 0; j <= sum; j++)            {                dp[i][j] = dp[i - 1][j];                for(int k = 1; k <= t[i]; k++)                {                    if(k > j) break;                    dp[i][j] += dp[i - 1][j - k];                    dp[i][j] %= MOD;                }            }        }        printf("%d\n", dp[n - 1][sum]);    }    return 0;}


0 0
原创粉丝点击