本帖最后由 python/print 于 2023-7-8 13:25 编辑
(求最佳答案)这段代码是背包问题的解法,但是存在以下几处错误:
1. 在主函数中,读入的物品个数m应该为m+1,因为物品的编号是从0到m-1。所以第一个循环应该是for(int i=0;i<=m;i++)。
2. 在dp函数中,第一个if条件语句判断v[0]与s的大小关系时,应该是if(v[0]>s),而不是if(v[0]>=s),因为根据题目描述,可以等于总钱数N。
3. 在第一个if条件语句中,需要添加对mem[0][s]的更新,即mem[0][s] = v[0] * p[0];,以确保初始问题的结果被正确保存到mem数组中。
(没办法,上面[s]貌似和论坛的冲突了,只能用代码框)
代码如下:
#include <stdio.h>
#define max(a,b) (a)>(b)?(a):(b)
long long v[28],p[28],mem[28][30001];
long long dp(int x,int s)
{
if(mem[x][s]!=0) return mem[x][s];
if(x==0)
{
if(v[0]>s)
{
return 0;
}
mem[0][s] = v[0] * p[0]; // 更新初始问题的结果
return mem[0][s];
}
if(v[x]>s)
{
mem[x-1][s]=dp(x-1,s);
return mem[x-1][s];
}
if(mem[x-1][s-v[x]]==0) mem[x-1][s-v[x]]=v[x]*p[x]+dp(x-1,s-v[x]);
if(mem[x-1][s]==0) mem[x-1][s]=dp(x-1,s);
return max(mem[x-1][s-v[x]],mem[x-1][s]);
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<=m;i++) // 修改循环条件
{
scanf("%lld%lld",&v[i],&p[i]);
}
printf("%lld\n",dp(m,n)); // 修改参数传递
return 0;
}
但是 这个思路可能还是解不了一些节点,我也不知道怎么回事,WA了,但是按照下方思路来,我试过是AC的 这个就是背包问题,可以使用动态规划来解决。
首先,创建一个二维数组dp[m+1][N+1],其中dp[j]表示在考虑前i件物品、总钱数不超过j的情况下,所能达到的最大总和。
然后,我们可以使用以下递推关系式来填充dp数组:
dp[j] = max(dp[i-1][j], dp[i-1][j-v] + v*w)
其中v表示第i件物品的价格,w表示第i件物品的重要度。
最后,所求的答案即为dp[m][N]。
|