HDU 5000

时间:2021-06-20 08:25:31

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

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

比赛的时候没有想到这题的关键点,没出来也是情理之中

解法:sum表示一个人的属性和。首先,人数最多的情况下这些人的sum是相同的,因为这种情况下一个属性减少另一个属性必然增加,保证满足条件。其次发现,sum=0的方案数和sum=ΣT[i]的方案数相同,因此在sum=(ΣT[i])/2取得最大值(没找到完整的推理,只是根据猜测。。)。这样问题转化为n个数,每个数可以取0-T[i],和为(ΣT[i])/2的方案数。

dp[i][j]表示选到第i个人时,属性和为j的种数

#include <iostream>
#include <cstdio>
#include <cstring> using namespace std ; const int mod= ; int T[],dp[][] ; int main()
{
int t ;
scanf("%d",&t) ;
while(t--)
{
int n ;
scanf("%d",&n) ;
int sum= ;
for(int i= ;i<n ;i++)
{
scanf("%d",&T[i]) ;
sum+=T[i] ;
}
memset(dp,,sizeof(dp)) ;
for(int i= ;i<=T[] ;i++)
dp[][i]= ;
sum>>= ;
for(int i= ;i<n ;i++)
{
for(int j= ;j<=sum ;j++)
{
for(int k= ;k<=T[i] ;k++)
{
if(j<k)break ;
dp[i][j]=(dp[i][j]+dp[i-][j-k])%mod ;
}
}
}
printf("%d\n",dp[n-][sum]) ;
}
return ;
}