hdu oj 5000 Clone DP

来源:互联网 发布:公安部网络监察局 编辑:程序博客网 时间:2024/06/05 11:17

看了一下别人的代码,这是一道01背包的变形。与01背包不同处是一个的值是确定的,一个的值是变化着的。

这道题是说这里有克隆人,克隆人有N个属性,如果存在一个克隆人的各个属性比另一个克隆人的相对应的属性都大,则另一个克隆人就要被杀死。现在给你N个属性值,求最多能有多少个克隆人存在。当其中的一个克隆人的一个属性为最大值,其他属性为0,为了保证该克隆人能继续存在,他的最大属性减小,另外的属性应该增大。通过实例说明,我们能发现当所有属性的和相等的情况下,属性和相等的克隆人是能共存的。现在要求能共存的克隆人达到最大,现在问题就是求属性和为多少时克隆人人数最大。采用极限法我们发现所有属性和的sum一半,即sum/2时,人数达到最大。dp[i][j+k]=(dp[i][j+k]+dp[i-1][j])%mod;表示当第i个属性为k时,前i个属性和为j+k时,前i-1个属性和为j的克隆人数+当前的已有值。

代码如下:

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int mod=1e9+7;long long dp[2005][2005];int main() {int t,i,j,k,T[2005];scanf("%d",&t);while(t--) {int sum=0,n;memset(dp,0,sizeof(dp));scanf("%d",&n);for(i=1; i<=n; i++) {cin>>T[i];sum+=T[i];}if(n==1) cout<<1<<endl;else {sum/=2; memset(dp, 0, sizeof dp);      for(i = 0; i <= T[1]; i++)          dp[1][i] = 1;      for(i = 2; i <= n; i++)      {          for(j = 0; j <= sum; j++) {              for(k = 0; k + j <= sum && k <= T[i]; k++)              {                  dp[i][k+j] = (dp[i][k+j] + dp[i-1][j]) % mod;              }          }      }  printf("%ld\n",dp[n][sum]);}}return 0;}


0 0