题目链接:点击打开链接
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int q[15][15];
int dp[100010];
int w[100010],p[100010],num[100010];
int k;
void zerobeibao(int cost,int weight ,int n)
{
for(int i=n; i>=cost; i--)
dp[i]=max(dp[i],dp[i-cost]+weight);
}
void wanquanbeibao(int cost ,int weight ,int n )
{
for(int i=cost; i<=n; i++)
{
dp[i]=max(dp[i],dp[i-cost]+weight);
}
}
int duochongbeibao(int c[],int w[],int num[],int n,int b)
{
memset(dp,0,sizeof(dp));
for(int i=1; i<k; i++)
{
if(num[i]*c[i]>b)
wanquanbeibao(c[i],w[i],b);
else
{
int k1=1;
while(k1<num[i])
{
zerobeibao(k1*c[i],k1*w[i],b);
num[i]-=k1;
k1<<=1;
}
zerobeibao(num[i]*c[i],num[i]*w[i],b);
}
}
return dp[b];
}
int main()
{
// int n,m;
int a,b;
scanf("%d%d",&a,&b);
memset(q,0,sizeof(q));
for(int i=0; i<a; i++)
{
int q1,q2;
scanf("%d%d",&q1,&q2);
q[q1][q2]++;
}
k=1;
for(int i=1; i<=10; i++)
for(int j=1; j<=10; j++)
{
if(q[i][j])
{
w[k]=i;
p[k]=j;
num[k]=q[i][j];
k++;
}
}
printf("%d\n",duochongbeibao(w,p,num,a,b));
return 0;
}原本是一个01背包,但是由于时间复杂度太大,超时,所以·看到后面的数据比较少,所以考虑转化为多重背包,其实思维性不大!!!!!!
贴上另外一道题hdu2192(悼念512)!!!
时间复杂度是O(n*v),然后01背包的时间复杂度是O(N^2),那个n是物品的种数,v是容量。
本文介绍了一种将01背包问题转换为多重背包问题的方法,并通过具体代码实现了解决方案。通过对物品数量的处理,有效降低了时间复杂度,提高了算法效率。
1641

被折叠的 条评论
为什么被折叠?



