dp题单-背包问题
1、Cut Ribbon
思路一:数据范围很小,考虑直接枚举。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n, p, q, r;
signed main(){
cin >> n >> p >> q >> r;
int ans = 0;
for(int i = 0; p * i <= n; i ++){
for(int j = 0; p * i + q * j <= n; j++){//第二层for循环枚举的时候,要包含i的范围
if((n - i * p - j * q) % r == 0){
ans = max(ans, i + j + (n - i * p - j * q) / r);
}
}
}
cout << ans << endl;
return 0;
}
思路二、考虑背包
完全背包(物品件数没有上限)。物品件数表示价值,长度表示体积。正常完全背包就可以。
2、Marvolo Gaunt's Ring
思路:每个位置上的数有两种状态,选或者不选,选了作为第几个数,作为第一个数?作为第二个数?作为第三个数?当前状态会与前一位的状态有关,考虑。
:前个数,选择个时的最优解。当时,表示的最优解。与之类似。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 10;
int dp[N][3], a[N], n, p, q, r;
signed main(){
cin >> n >> p >> q >> r;
memset(dp, -0x3f, sizeof dp);
for(int i = 1; i <= n; i++){
cin >> a[i];
}
for(int i = 1; i <= n; i++){
dp[i][0] = max(dp[i - 1][0], p * a[i]);
dp[i][1] = max(dp[i][0] + a[i] * q, dp[i - 1][1]);//当j = 1时,要从dp[i][0]选
dp[i][2] = max(dp[i][1] + a[i] * r, dp[i - 1][2]);
}
cout << dp[n][2] << endl;
return 0;
}
3、Dima and Salad
小总结:遇到公式的时候,先对公式进行化简。
思路:把作为体积,价值为。但是题目中的每个i对应的体积可能有正有负,这时候分别处理正负两种情况。我觉得这个地方是整道题思路最妙的地方。值得学习。
题解:https://www.luogu.com.cn/problem/solution/CF366C
4、Caesar's Legions
本文作者:风归去
本文链接:https://www.cnblogs.com/N-lim/p/16900006.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步