洛谷题单指南-动态规划1-P1802 5 倍经验日
原题链接:https://www.luogu.com.cn/problem/P1802
题意解读:x个药取打n个怪,打赢打输都有经验,计算最大的经验数,跟01背包类似,可以理解为一个物品装得下或者装不下都可以装,装得下获得的价值高,装不下获得的价值低。
解题思路:
设lose[N], win[N], use[N]表示失败时获得的经验,胜利时获得的经验和打过要至少使用的药数量;
设dp[i][j]表示用j个药打前i个怪所能获得的最大经验;
当j >= use[i]时,可以选择打赢或者打输dp[i][j] = max(dp[i-1][j] + lose[i], dp[i-1][j-use[i]] + win[i]),注意打输是dp[i-1][j] + lose[i],j优先用来打前i-1,剩下的再对i打输,这样才是最优;
当j < use[i]时,只能打输,把药优先打前i-1个怪,dp[i][j] = dp[i-1][j] + lose[i]。
100分代码(二维):
#include <bits/stdc++.h>
using namespace std;
const int N = 1005;
int n, x;
int lose[N], win[N], use[N];
int dp[N][N]; //dp[i][j]表示前i个人j个药能获得的最大经验
int main()
{
cin >> n >> x;
for(int i = 1; i <= n; i++) cin >> lose[i] >> win[i] >> use[i];
for(int i = 1; i <= n; i++)
{
for(int j = 0; j <= x; j++)
{
dp[i][j] = dp[i-1][j] + lose[i]; //药剂j不够打i,只能打败
if(j >= use[i]) dp[i][j] = max(dp[i][j], dp[i-1][j-use[i]] + win[i]); //药剂j够打i,可以打赢或者打输
}
}
cout << 5ll * dp[n][x] << endl;
return 0;
}
100分代码(一维):
#include <bits/stdc++.h>
using namespace std;
const int N = 1005;
int n, x;
int lose[N], win[N], use[N];
int dp[N]; //dp[j]表示j个药能获得的最大经验
int main()
{
cin >> n >> x;
for(int i = 1; i <= n; i++) cin >> lose[i] >> win[i] >> use[i];
for(int i = 1; i <= n; i++)
{
for(int j = x; j >= 0; j--)
{
if(j >= use[i]) dp[j] = max(dp[j] + lose[i], dp[j-use[i]] + win[i]); //药剂j够打i,可以打赢或者打输
else dp[j] += lose[i]; //药剂j不够打i,只能打败
}
}
cout << 5ll * dp[x] << endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】