hdu5000 Clone 鞍山网络赛D题

Clone

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 382    Accepted Submission(s): 186


Problem Description
After eating food from Chernobyl, DRD got a super power: he could clone himself right now! He used this power for several times. He found out that this power was not as perfect as he wanted. For example, some of the cloned objects were tall, while some were short; some of them were fat, and some were thin.

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.
 

Input
The first line contains an integer T, denoting the number of the test cases.

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].
 

Output
For each test case, output an integer representing the answer MOD 10^9 + 7.
 

Sample Input
  
  
2 1 5 2 8 6
 

Sample Output
  
  
1 7
 
  比赛的时候都注意到了说T[i]的和不超过2000,也就是说应该和T[i]的和有关系,结果还是没弄出来,看了题解,想想确实是这么回事。。

  每组的值和为一个定值的时候,这组都可以共存,并且不可能跟和为其他值的组共存,因为若有一组和为其他值,如果那个值比这个值大,这组至少有1个被吃掉,反之那组被吃掉。

  这个定值取所有T[i]的和除以2,这种情况可以有最多组共存。

  dp[i][j]表示前i维和为j有多少种情况,最后答案是dp[N][(sum+1)/2]。这题难在发现和为定值,并且和为(sum+1)/2。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 2010
#define MOD 1000000007
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
int T;
LL N,a[MAXN],dp[MAXN][MAXN];
int main(){
    freopen("in.txt","r",stdin);
    scanf("%d",&T);
    while(T--){
        scanf("%I64d",&N);
        LL sum=0;
        for(int i=1;i<=N;i++){
            scanf("%I64d",&a[i]);
            sum+=a[i];
        }
        sum=(sum+1)/2;
        memset(dp,0,sizeof(dp));
        dp[0][0]=1;
        for(int i=1;i<=N;i++)
            for(int j=0;j<=a[i];j++)
                for(int k=j;k<=sum;k++) dp[i][k]=(dp[i][k]+dp[i-1][k-j])%MOD;
        printf("%I64d\n",dp[N][sum]);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值