0
点赞
收藏
分享

微信扫一扫

ZCMU - 1381: 简单题


题目链接:​​点击打开链接​​

题目大意:略。

解题思路:多重背包。

AC 代码

#include<bits/stdc++.h>

#define mem(a,b) memset(a,b,sizeof a)

using namespace std;

typedef long long ll;

const int MAXN = 10000;

int dp[MAXN];
int val[MAXN],weight[MAXN],num[MAXN];
int n,m;

void ZeroOne_Pack(int val,int weight,int m)
{
for(int j=m;j>=weight;j--)
if(j==weight || dp[j-weight]!=0) // 判断状态是否可转移
dp[j]=max(dp[j],dp[j-weight]+val);
}

void Complete_Pack(int val,int weight,int m)
{
for(int j=weight;j<=m;j++)
if(j==weight || dp[j-weight]!=0) // 判断状态是否可转移
dp[j]=max(dp[j],dp[j-weight]+val);
}

int Multi_Pack(int val[],int weight[],int n,int m)
{
mem(dp,0);
for(int i=0;i<n;i++)
{
if(num[i]*weight[i]>m)
{
Complete_Pack(val[i],weight[i],m);
}
else
{
int k=1;
while(k<num[i])
{
ZeroOne_Pack(k*val[i],k*weight[i],m);
num[i]-=k;
k<<=1;
}
ZeroOne_Pack(num[i]*val[i],num[i]*weight[i],m);
}
}
return dp[m];
}

int main()
{
int n,m=8500;
while(~scanf("%d",&n) && n)
{
// for(int i=0;i<n;i++)
// scanf("%d%d",&val[i],&weight[i]);
//
// int rs=ZeroOne_Pack(val,weight,m);
//
//
// int rs=Complete_Pack(val,weight,m);


for(int i=0;i<n;i++)
{
scanf("%d%d",&weight[i],&num[i]);
val[i]=weight[i]; // 根据题意,价值和重量是等价的
}

Multi_Pack(val,weight,n,m);

sort(dp,dp+m+1);

// for(int i=0;i<=m;i++)
// {
// printf("%d ",dp[i]);
// }
// puts("");

int i,j=1;
for(i=0;i<=m;i++)
{
if(dp[i]!=0)
{
if(dp[i]==j)
{
j++;
}
else // 匹配不上,说明此时的 j 就是最小称不到的量
{
printf("%d\n",j);
break;
}
}
}

if(i==m+1) // 匹配完了标记,则 dp[m]+1 为最终结果
{
printf("%d\n",dp[m]+1);
}
}

return 0;
}


举报

相关推荐

ZCMU—A

ZCMU—1478

ZCMU—1263

ZCMU—1374

ZCMU—1306

ZCMU—1798

ZCMU—1776

ZCMU—1676

0 条评论