您的位置:首页 > 其它

poj 1742 多重背包可行性

2013-08-19 18:49 309 查看
简单的方法来自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;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: