P3985 不开心的金明

  • 这道题好像是01背包,但价格 v[i]109 级别的,意味着dp数组的第一维要开到 109,显然不可能

  • 题目中说:

对所有的 i=1,2,3,,Nmin(vi)vimin(vi)+3.

  • 也就是 v[i] 的最大值最小值的差不大于3,由此想到把每个 v[i] 减去 v[i]min1,再按照01背包去做

  • 但是都减去一个数后无法通过一般的01背包的dp数组确定“考虑了前 i 件物品,总价为 j”中的 j,所以要把状态表示改变一下

状态表示

dp[j][k]ikv[i]min1j

  • 所以转移方程如下

dp[j][k]=max(dp[j][k],dp[jv[i]][k1]+p[i])

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int INF=1e9;
int n,w;
int mini=INF,sum,maxi;
struct Obj{
int v,p;
}in[101];
int dp[1001][1001];
signed main(){
// freopen("1.in","r",stdin);
cin>>n>>w;
for(int i=1;i<=n;i++){
cin>>in[i].v>>in[i].p;
sum+=in[i].v;
mini=min(mini,in[i].v);
}
mini--;
sum-=mini*n;
for(int i=1;i<=n;i++)
in[i].v-=mini;
for(int i=1;i<=n;i++){
for(int j=sum;j>=in[i].v;j--){
for(int k=1;k<=n;k++){
if(j+mini*k<=w)
dp[j][k]=max(dp[j][k],dp[j-in[i].v][k-1]+in[i].p);
}
}
}
for(int i=1;i<=sum;i++){
for(int j=1;j<=n;j++)
maxi=max(maxi,dp[i][j]);
}
cout<<maxi<<"\n";
}
posted on   Bubble_e  阅读(35)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!



点击右上角即可分享
微信分享提示