Clone
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 447 Accepted Submission(s): 215
More evidence showed that for two clones A and B, if A was no worse than B in all fields, then B could not survive. More specifically, DRD used a vector v to represent each of his clones. The vector v has n dimensions, representing a clone having N abilities. For the i-th dimension, v[i] is an integer between 0 and T[i], where 0 is the worst and T[i] is the best. For two clones A and B, whose corresponding vectors were p and q, if for 1 <= i <= N, p[i] >= q[i], then B could not survive.
Now, as DRD's friend, ATM wants to know how many clones can survive at most.
For each test case: The first line contains 1 integer N, 1 <= N <= 2000. The second line contains N integers indicating T[1], T[2], ..., T[N]. It guarantees that the sum of T[i] in each test case is no more than 2000 and 1 <= T[i].
題意:一個克隆人有n個屬性,如果一個克隆人的任何一個屬性都不大於另一個,他就不應該存在,給你n和每個屬性的最大值,問最多能有多少克隆人存在。
思路:如果說能保證最多的克隆人存在,那麼他們的屬性和一定相等,且爲所有最大屬性和的一半。(好像很有道理,卻說不出來哪有道理的結論)。比賽的時候神犇推得出來揹包一下就過掉了,我這樣的小菜做這種題只能靠yy了。知道結論直接01揹包求能到達sum/2的所有情況就好了。
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
const int mod=1e9+7;
const int N=2005;
int dp[N*N/2],a[N];
int main()
{
int n,t,sum;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
sum=0;
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
sum+=a[i];
}
sum/=2;
memset(dp,0,sizeof(dp));
dp[0]=1;
for(int i=0;i<n;i++){
for(int j=sum;j>=0;j--){
for(int k=1;k<=a[i]&&k<=j;k++)
dp[j]=(1ll*dp[j]+dp[j-k])%mod;
}
}
printf("%d\n",dp[sum]);
}
return 0;
}