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 }

 

posted @ 2012-12-06 23:27  silver__bullet  阅读(151)  评论(0编辑  收藏  举报