poj 3093 01背包

View Code
/*
给你n个物品,每个物品有一定的体积,给你一个总体积一定的背包,
问你用这个背包去装这些物品的时候,背包中的物品共有几种不同的组合
一种组合是合法的:剩下的背包容量必须《剩下的物品的体积的最小值
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int dp[1010];
int v[50];
int max(int a,int b){
    return a>b?a:b;
}
int main(){
    int t,i,j,k,V,D,ca=1;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&V,&D);
        for(i=1;i<=V;i++)   scanf("%d",&v[i]);
        sort(v+1,v+V+1);int sum=0,ans=0;
        for(i=1;i<=V;i++){//枚举未选集合中最小的商品,那比他小的肯定都已经在背包里了
            memset(dp,0,sizeof(dp));dp[0]=1;dp[sum]=1;
            for(j=i+1;j<=V;j++)
                for(k=D;k>=v[j]+sum;k--)
                    dp[k]+=dp[k-v[j]];
                for(j=D;j>=max(D-v[i]+1,1);j--)//保证D-j+1<=v[i];
                    if(j>=sum) ans+=dp[j];
                    sum+=v[i];
        }
        printf("%d %d\n",ca++,ans);
    }
}
posted @ 2012-04-29 14:00  Because Of You  Views(354)  Comments(0Edit  收藏  举报