DP - hdu5000 Clone

题目:

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


题意:

某君拥有n个属性值,某天闲着无聊克隆了若干个自己,若克隆体A的每格属性均大于等于克隆体B,则克隆体B会被杀死,给出n个属性值的上限,问最多能存活几个克隆体


思路:

数据量极小的问题一般都是DP = = 数据量极小的题一般都是DP = = 数据量极小的题一般都是DP = =

题目备注了所有属性上限之和小于2000,先观察下测试数据

1 5 活下来的有六个集合的可能 {(5)} {(4)} {(3)} {(2)} {(1)} {(0)}

2 8 6 活下来的有三个集合的可能 {(0,6)(1,5)(2,4)(3,3)(4,2)(5,1)(6,0)}  {(1,6)(2,5)(3,4)(4,3)(5,2)(6,1)(7,0)}  {(2,6)(3,5)(4,4)(5,3)(6,2)(7,1)(8,0)}

观察到其实活下来的每个集合的每个克隆体,其实属性和是一样的,再多算几组数据加上大胆猜测,不难发现属性和为sum/2的集合始终是最终答案,则问题转变成,给定ΣT[i]个数,问有多少种可能组成和为sum/2,01背包问题


代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

const int MOD = 1e9+7;

long long dp[2005][1005];
int arr[2005];

int main(){
    int total;
    int i,n,j,k;
    cin>>total;
    while (total--){
        int sum = 0;
        scanf("%d",&n);
        for (i=0;i<n;++i){
            scanf("%d",arr+i);
            sum += arr[i];
        }
        sum /= 2;
        memset(dp,0,sizeof(dp));
        for (i = 0;i<=arr[0];++i)
            dp[0][i] = 1;
        for (i=1;i<n;++i){
            for (j=0;j<=arr[i];++j){
                for (k=sum-j;k>=0;--k){
                    dp[i][k+j] += dp[i-1][k];
                    dp[i][k+j] %= MOD;
                }
            }
        }
        cout<<dp[n-1][sum]<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值