20230223周四晚上
动态规划的思想:对第一个或最后一个阶段进行分类讨论。
看到这道题的思路,传统的思维方式来说,要对走过的格子进行分类讨论。
dp 数组的状态肯定不能只是 dp[i] ,那样子做不能知道用过的卡牌数————>用多了一堆卡牌还不知道......
目前的状态:dp[i][f1][f2][f3][f4]——>选到i的时候,使用了f1张走一个格子的牌,f2~ ~ ,f3 ~ ,f4 ~ ~时候最多的积分。
这个时候可以看得出来,时间和空间都过不了。
优化吧,观察这个状态,它已经包含了所有卡牌的使用情况,并且要思考题目:走到的位置,实际上取决于卡牌。可以通过卡牌的数量推出 i ,完全可以把 i 的状态删掉。
#include<bits/stdc++.h>
using namespace std;
int n,m,t,dp[41][41][41][41];
int a[500],b[5];
int main() {
cin>>n>>m;
for(int i=1;i<=n;i++) {
cin>>a[i];
}
for(int i=1;i<=m;i++) {
cin>>t;
b[t]++;
}
for(int f1=0;f1<=b[1];f1++) {
for(int f2=0;f2<=b[2];f2++) {
for(int f3=0;f3<=b[3];f3++) {
for(int f4=0;f4<=b[4];f4++) {
dp[f1][f2][f3][f4]=max(max(dp[f1][f2][f3][f4],dp[max(f1-1,0)][f2][f3][f4]),max(max(dp[f1][max(f2-1,0)][f3][f4],dp[f1][f2][max(f3-1,0)][f4]),dp[f1][f2][f3][max(f4-1,0)]))+a[1+f1*1+f2*2+f3*3+f4*4];
}
}
}
}
cout<<dp[b[1]][b[2]][b[3]][b[4]];
return 0;
}
(其实有一些比较奇妙的方法,比如通过 i f1 f2 f3 推f4,也不是不行。时间稍微有一点紧迫。但是我认为这种方法是传统的思维。--> 并不一定要通过位置为阶段 )
T2
原题链接
饥饿的奶牛
题目描述
有一条奶牛冲出了围栏,来到了一处圣地(对于奶牛来说),上面用牛语写着一段文字。
现用汉语翻译为:
有
对于奶牛来说,自然是吃的越多越好,然而奶牛智商有限,现在请你帮助他。
输入格式
第一行一个整数
接下来
输出格式
输出最多能吃到的牧草堆数。
样例 #1
样例输入 #1
3
1 3
7 8
3 4
样例输出 #1
5
提示
- 按照区间来进行dp;
一般来说,对于含有区间的问题,对区间进行分类讨论。
观察这一题,首先对区间的右端点排序一波。
然后我们就可以对一个或者最后一个进行分类讨论,在本题中,对于选到第 n 个区间时的最优解,我们可以选择选和不选,不选的话直接继承上一次的最优解,选的话就要从之前的合法区间内选一个取得最优解
本文作者:cjrqwq
本文链接:https://www.cnblogs.com/yfzqwq/p/18492839
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步