hdu5000
题目
就是说一些人,每个人有一些能力值,如果某个人在每个能力值上都不比另一个人少,那么另一个人就不能和他同存,现给你能力的个数以及每种能力的上限,问最多有多少人可以同存。
思路
关键还是思路,对于能力值总和相同的人来说,他们是一定能够共存的,因为此消彼长,我这方面强在另一方面就比他弱。然后就是猜了(貌似有证明),在能力值总和为总能力值总和sum的一半的时候,人数最多,也就是像对于方程t1+t2+……tn=sum/2的解有多少种这种问题。dp[i][j]就表示到ti的时候,总和为j的个数,dp[i][j]=(dp[i][j]+dp[i-1][j-k])%mod,枚举k即可。
代码
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
const int maxn=2010;
const int mod=1e9+7;
int a[maxn];
int dp[maxn][maxn];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int sum=0;
int n;
scanf("%d",&n);
for(int i=0; i<n; i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
sum/=2;
memset(dp,0,sizeof(dp));
for(int i=0; i<=a[0]; i++)
dp[0][i]=1;
for(int i=1; i<n; i++)
for(int j=0; j<=sum; j++)
for(int k=0; k<=a[i]&&k<=j; k++)
dp[i][j]=(dp[i][j]+dp[i-1][j-k])%mod;
printf("%d\n",dp[n-1][sum]);
}
return 0;
}