题意可抽象为:N个包中每个包容量是T[i],每个包都拿一些,设拿出的总数为sum时的方案数为q,求max(q)
设dp[i][j]为拿了前i个包,共拿出了j物品时的方案数。那么
for i=1 to n
for j=0 to sum
for k=0 to t[i]
dp[i][j]+=dp[i-1][j-k]
但是注意这题中间过程就得取MOD,然而这题求的却是最大值取模而不是取模之后的最大值 【这俩并不一样
可以打表得知dp[N][sum{T[i]}/2]是最大值
1 #include <iostream> 2 #include<cstring> 3 #define MOD 1000000007 4 #define LL long long 5 using namespace std; 6 int N,T; 7 LL sum; 8 int t[2010]; 9 int dp[2010][2010]; 10 11 int main() 12 { 13 cin>>T; 14 while(T--) 15 { 16 memset(dp,0,sizeof(dp)); 17 sum=0; 18 19 cin>>N; 20 for(int i=1;i<=N;i++) 21 { 22 cin>>t[i]; 23 sum+=t[i]; 24 } 25 26 //cout<<sum<<endl; 27 sum=sum/2; 28 //cout<<sum<<endl; 29 30 for(int i=0;i<=t[1];i++) 31 dp[1][i]=1; 32 33 for(int i=2;i<=N;i++) 34 for(int j=0;j<=sum;j++) 35 for(int k=0;k<=t[i];k++) 36 if(j>=k) 37 { 38 //cout<<i%2<<" "<<(i-1)%2<<endl; 39 dp[i][j]+=dp[i-1][j-k]; //dp[i][j]+=dp[i-1][j-k] 40 dp[i][j]=dp[i][j]%MOD; 41 } 42 43 44 cout<<dp[N][sum]<<endl; 45 } 46 47 return 0; 48 }