洛谷p1541 乌龟棋
Topic meaning:求出可获得的最高得分
Topic of solving:动态规划
由于每一个点的分值可能不同,因此不同的卡牌使用顺序可能得到不同的分值,即如果我们能求得最佳的卡牌使用顺序即求出了最高的得分。
先按照暴力的思路来即求出所有的卡牌使用顺序可以得到的分值,而后得到最大的分值,那么会发现存在可以进行简化的部分
如有顺序1:1 1 3 2 4 5 顺序2:1 3 1 5 4 2
发现顺序1,2前三张卡牌的使用最后达到的位置是一样的均为6,而不同的是这前三张牌所取得的分值,那么对于这前三张牌我们就应该取可以得到的最大分值,
因为顺序1,2均是1牌使用2次,3牌使用1次,其对卡牌的使用在数量上是一致的,而题目明确最后一定会用完全部卡牌,则我们就可以以卡牌数量为阶段进行状态之间的转移
求得用光所有卡牌数后可得到的最大分值,而无需多考虑卡牌使用次序。
#include<iostream>
using namespace std;
int n,m,f[45][45][45][45],a[5],v[405];
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>v[i];
for(int i=1;i<=m;i++) {
int t;
cin>>t;
a[t]++;
}
for(int i1=0;i1<=a[1];i1++)
for(int i2=0;i2<=a[2];i2++)
for(int i3=0;i3<=a[3];i3++)
for(int i4=0;i4<=a[4];i4++){
int t=i1+i2*2+i3*3+i4*4+1;
if(i1<a[1]&&t+1<=n) f[i1+1][i2][i3][i4]=max(f[i1+1][i2][i3][i4],f[i1][i2][i3][i4]+v[t+1]);
if(i2<a[2]&&t+2<=n) f[i1][i2+1][i3][i4]=max(f[i1][i2+1][i3][i4],f[i1][i2][i3][i4]+v[t+2]);
if(i3<a[3]&&t+3<=n) f[i1][i2][i3+1][i4]=max(f[i1][i2][i3+1][i4],f[i1][i2][i3][i4]+v[t+3]);
if(i4<a[4]&&t+4<=n) f[i1][i2][i3][i4+1]=max(f[i1][i2][i3][i4+1],f[i1][i2][i3][i4]+v[t+4]);
}
cout<<f[a[1]][a[2]][a[3]][a[4]]+v[1];
return 0;
}

浙公网安备 33010602011771号