poj 1742 多重背包可行性

简单的方法来自http://poj.org/showmessage?message_id=156697

#include<stdio.h>
#include<string.h>
int dp[100010];
int num[110],v[110];
int used[100010];
int main(){
	int n,m,i,j;
	while(scanf("%d%d",&n,&m),(n||m)){
		for(i=0;i<n;i++) scanf("%d",&v[i]);
		for(i=0;i<n;i++) scanf("%d",&num[i]);
		memset(dp,0,sizeof(dp));
		dp[0]=1;
		int ans=0;
		for(i=0;i<n;i++){
             memset(used,0,sizeof(used));
			 for(j=v[i];j<=m;j++){
				 if(!dp[j]&&dp[j-v[i]]&&used[j-v[i]]<num[i]){
					 ans++;
					 dp[j]=1;
					 used[j]=used[j-v[i]]+1;
				 }
			 }
		}
		printf("%d\n",ans);
	}
   return 0;
}

  多重背包倍增

#include<cstdio>
using namespace std;
const int mm=111111;
const int mn=111;
int a[mn],c[mn];
bool f[mm];
int n,m;
void CompletePack(int v)
{
    for(int i=v;i<=m;++i)f[i]|=f[i-v];
}
void ZeroOnePack(int v)
{
    for(int i=m;i>=v;--i)f[i]|=f[i-v];
}
int main()
{
    int i,j,ans;
    while(scanf("%d%d",&n,&m),n+m)
    {
        for(i=0;i<n;++i)scanf("%d",&a[i]);
        for(i=0;i<n;++i)scanf("%d",&c[i]);
        for(i=f[0]=1;i<=m;++i)f[i]=0;
        for(i=0;i<n;++i)
        if(c[i])
            if(c[i]*a[i]>=m)CompletePack(a[i]);
            else
            {
                j=1;
                while(j<c[i])
                {
                    ZeroOnePack(a[i]*j);
                    c[i]-=j;
                    j<<=1;
                }
                ZeroOnePack(a[i]*c[i]);
            }
        ans=0;
        for(i=1;i<=m;++i)ans+=f[i];
        printf("%d\n",ans);
    }
    return 0;
}

  

posted @ 2011-11-21 03:18  Because Of You  Views(322)  Comments(0Edit  收藏  举报