poj 3093 Margaritas on the River Walk
题意:给定n个物品,用这n个物品填充一个背包,使得没有被装入的物品一定塞不进背包,统计方案数。
解法:对于普通的01背包统计方案数很简单,dp[j]=dp[j]+dp[j-w[i]]...这题需要对重量进行排序,然后枚举每个物品,使之成为没有被装入背包的最小重量,那么对于重量小于w[i],的,一定会被装入背包,对于大于w[i]的,我们只需要进行一次01背包统计方案即可,最后找出满足条件的累加。。。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define N 1010 5 #define M 35 6 using namespace std; 7 int w[M],dp[N]; 8 int main(){ 9 int n,m; 10 int t,cas=1; 11 scanf("%d",&t); 12 while(t--){ 13 scanf("%d%d",&n,&m); 14 for(int i=1;i<=n;i++)scanf("%d",&w[i]); 15 sort(w+1,w+1+n); 16 if(w[1]>m){ 17 printf("%d %d\n",cas++,0); 18 continue; 19 } 20 int ans=0,sum=0; 21 for(int i=1;i<=n;i++){ 22 sum=0; 23 for(int j=1;j<i;j++)sum+=w[j]; 24 if(sum>m)break; 25 memset(dp,0,sizeof(dp)); 26 dp[sum]=1; 27 for(int j=i+1;j<=n;j++){ 28 for(int k=m;k>=w[j]+sum;k--) 29 dp[k]=dp[k]+dp[k-w[j]]; 30 } 31 for(int j=m;j>=m-w[i]+1;j--) 32 if(j>=sum)ans+=dp[j]; 33 } 34 printf("%d %d\n",cas++,ans); 35 } 36 return 0; 37 }