【01背包问题】【AsiaRegionalAnshanOnline2014】HDU5000Clone

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

英文题必备翻译:有n种属性,每种属性的数值可以是0-T[i],当一个人属性全部小于等于另一个人的属性时,小的那个人会被淘汰,问最多同时存在多少人。

好吧,想到来关键点就比较容易。只要我们明白在M/2的情况下方案数是最多的,并且当属性和为一个数时的各种方案都存在。

通过枚举各个数据,方案数dp[s]=dp[s]+dp[s-j];

#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<map>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#include<vector>
#include<algorithm>
#define LL long long
#define inf 1<<29
#define s(a) scanf("%d",&a)
#define CL(a,b) memset(a,b,sizeof(a))
using namespace std;
const int N=2005;
const int mod = 1e9+7;
string s1,s2;
int n,M,dp[N],a[N];
int solve(int m)
{
    CL(dp,0);
    dp[0]=1;
    for(int i=1;i<=n;i++){
        for(int s=m;s>0;s--){
            for(int j=1;j<=a[i]&&j<=s;j++){
                dp[s]=(dp[s]+dp[s-j])%mod;
            }
        }
    }
    return dp[m];
}
int main()
{
    int t;
    s(t);
    while(t--){
        s(n);
        M=0;
        for(int i=1;i<=n;i++){
            s(a[i]);
            M+=a[i];
        }
        printf("%d\n",solve(M/2));
    }
    return 0;
}


你可能感兴趣的:(01背包,HDU5000)