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;

}

  

你可能感兴趣的:(poj)