洛谷p1541 乌龟棋

Topic Links

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;
}

 

posted @ 2019-11-06 23:15  Evolutw  阅读(132)  评论(0)    收藏  举报