1 条题解
-
0
自动搬运
来自洛谷,原作者为

违规用户名U56916
故地重游,还是怀念搬运于
2025-08-24 21:56:54,当前版本为作者最后更新于2018-04-11 16:49:27,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
莫名其妙找了这道题,然后莫名其妙的做了好几天。想看题解发现是个dfs记忆剪枝,不是动规于是自己苦打终于打出来了
其实这是一道很好的背包题
费用是一维————————挂钩
但是我没有敢压缩状态,所以开了二维数组
f[i][j]表示前i件物品在有j个挂钩的情况下的最大价值
然后状态转移为
f[i][j]=max(f[i-1][j],f[i-1][j-w[i]+1]+v[i])这是错的
因为j-w[i]+1可能是个负数,没有意义,这时候就要考虑这物品直接挂在手机上即j=1,也就需要我们把j-w[i]和0取最大值保证有意义
所以正解方程为f[i][j]=max(f[i-1][j],f[i-1][max(j-w[i].a,0)+1]+w[i].b);//这里的a是钩子,b是价值
为什么我用结构体呢?
并不是我闲的*疼,而是我们要进行一个排序让钩子多的在前面先计算,这个因为把钩子少的先计算很有可能多次挂在手机上没有意义
然后赋初值
我们应该把不可能的情况赋成极小值即
for(int i=0;i<=n;i++) f[0][i]=MAXN,f[i][n+1]=MAXN;
然后f[0][1]=0这是初始状态
下面贴AC代码
#include<bits/stdc++.h>//注意万能头比赛不能用 using namespace std; const int MAXN=-1000000000; int f[3010][3010];//蒙的数据范围 struct wu{ int a,b; }w[3010]; bool cmp(wu i,wu j){ return i.a>j.a; } int ans=-2147483647; int main(){ int n; cin>>n; for(int i=1;i<=n;i++) scanf("%d%d",&w[i].a,&w[i].b); sort(w+1,w+1+n,cmp); for(int i=0;i<=n;i++) f[0][i]=MAXN,f[i][n+1]=MAXN; f[0][1]=0; for(int i=1;i<=n;i++){ for(int j=0;j<=n;j++){ f[i][j]=max(f[i-1][j],f[i-1][max(j-w[i].a,0)+1]+w[i].b); } } for(int i=0;i<=n;i++) ans=max(ans,f[n][i]);//每个钩子都有可能 cout<<ans; return 0; }
- 1
信息
- ID
- 3097
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者