Codeforces 1176 F Destroy it! —— 记忆化搜索

This way

题意:

现在有n次游戏,每次都会有a[i]张牌,每张牌都会有一个花费和价值,每次游戏你拿的牌的花费不能超过3,当你拿完的时候,剩下的牌就被摧毁掉,并开始下一局游戏。如果你当前拿的牌的数量是10的倍数次,那么你当前这张牌的价值就会*2.问你最终最大价值是多少。

题解:

这种状态固定,并且靠枚举的题目一看就是记忆化搜索了。
那么 d p [ i ] [ j % 10 ] dp[i][j\%10] 就表示到了第i次游戏,手上的牌的数量是j的时候,之后的答案最大是多少。
那么接下来就只有六种情况:
1,1 1,1 1 1,2,2 1,3

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=2e5+5;
struct node{
    int num[4]={0};
    vector<ll>vec[4];
}p[N];
ll dp[N][10];
int n,m;
ll dfs(int pos,int res){
    if(pos>n)
        return 0;
    if(~dp[pos][res])
        return dp[pos][res];
    ll ans=0;
    ans=dfs(pos+1,res);
    if(p[pos].num[1]){
        ll add=p[pos].vec[1][0];
        if(res==9)
            add*=2;
        ans=max(ans,add+dfs(pos+1,(res+1)%10));

        if(p[pos].num[2]){
            add=p[pos].vec[1][0]+p[pos].vec[2][0];
            if(res>=8)
                add+=max(p[pos].vec[1][0],p[pos].vec[2][0]);
            ans=max(ans,add+dfs(pos+1,(res+2)%10));
        }
    }
    if(p[pos].num[2]){
        ll add=p[pos].vec[2][0];
        if(res==9)
            add*=2;
        ans=max(ans,add+dfs(pos+1,(res+1)%10));
    }
    if(p[pos].num[1]>=2){
        ll add=p[pos].vec[1][0]+p[pos].vec[1][1];
        if(res>=8)
            add+=p[pos].vec[1][0];
        ans=max(ans,add+dfs(pos+1,(res+2)%10));
    }
    if(p[pos].num[1]>=3){
        ll add=p[pos].vec[1][0]+p[pos].vec[1][1]+p[pos].vec[1][2];
        if(res>=7)
            add+=p[pos].vec[1][0];
        ans=max(ans,add+dfs(pos+1,(res+3)%10));
    }
    if(p[pos].num[3]){
        ll add=p[pos].vec[3][0];
        if(res==9)
            add*=2;
        ans=max(ans,add+dfs(pos+1,(res+1)%10));
    }
    dp[pos][res]=ans;
    return ans;
}
bool cmp(ll a,ll b){return a>b;}
int main()
{
    memset(dp,-1,sizeof(dp));
    scanf("%d",&n);
    int c;
    ll v;
    for(int i=1;i<=n;i++){
        scanf("%d",&m);
        while(m--){
            scanf("%d%lld",&c,&v);
            p[i].num[c]++;
            p[i].vec[c].push_back(v);
        }
        for(int j=1;j<=3;j++)
            if(p[i].num[j])
                sort(p[i].vec[j].begin(),p[i].vec[j].end(),cmp);
    }
    printf("%lld\n",dfs(1,0));
    return 0;
}

发布了554 篇原创文章 · 获赞 31 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/tianyizhicheng/article/details/104456535
今日推荐