• 捡金币


    time:3s 难度:Day2 T3
    长长的题面
    这里写图片描述
    这里写图片描述
    这里写图片描述
    这里写图片描述

    这是一道好难的题。
    正解是DP+单调队列。(蒟蒻不会啦,看了题解也迷迷糊糊)
    我只写了一个裸的DP,期望值60分,意外惊喜地拿了80分,好开心。
    我们枚举时间,f[t][i][j][k]表示第t秒站在(i,j),已经用了k次闪现所获得的最大金币数
    转移方程见代码,还是比较容易理解的。(对于 t 我是从零开始存的)
    时间复杂度:T*C*W*n*n ≈ 5*10^7 ,60%,3s大概是能过的

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #define LL long long
    #define INF 1000000007
    using namespace std;
    int n,C,W,T,ans;
    int s[101][26][26];
    int f[101][26][26][151];//f[t][i][j][k]表示第t秒站在(i,j),已经用了k次闪现所获得的最大金币数 
    int MAX(int &x,int y){if(y>x) x=y;}//取大 
    bool judge(int x,int y)
    {
        if(x<=n&&x>=1&&y<=n&&y>=1) return 1;
        return 0;
    }
    int main()
    {
        scanf("%d%d%d%d",&n,&C,&W,&T);
        for(int i=1;i<=T;i++) 
        for(int j=1;j<=n;j++) 
        for(int k=1;k<=n;k++) scanf("%d",&s[i][j][k]);
    
        for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) f[0][i][j][0]=s[1][i][j];
        for(int t=1;t<T;t++)
        {
            for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            for(int k=0;k<=W;k++)
            {
                MAX(f[t][i][j][k],f[t-1][i][j-1][k]+s[t+1][i][j]);//右走 
                MAX(f[t][i][j][k],f[t-1][i][j+1][k]+s[t+1][i][j]);//左走 
                MAX(f[t][i][j][k],f[t-1][i+1][j][k]+s[t+1][i][j]);//下走 
                MAX(f[t][i][j][k],f[t-1][i-1][j][k]+s[t+1][i][j]);//上走 
                MAX(f[t][i][j][k],f[t-1][i][j][k]+s[t+1][i][j]);//不动 
                for(int p=1;p<=C;p++)//闪现 
                {
                    if(k-p>=0)
                    {
                        if(judge(i,j-p*2)) MAX(f[t][i][j][k],f[t-1][i][j-p*2][k-p]+s[t+1][i][j]);
                        if(judge(i,j+p*2)) MAX(f[t][i][j][k],f[t-1][i][j+p*2][k-p]+s[t+1][i][j]);
                        if(judge(i-p*2,j)) MAX(f[t][i][j][k],f[t-1][i-p*2][j][k-p]+s[t+1][i][j]);
                        if(judge(i+p*2,j)) MAX(f[t][i][j][k],f[t-1][i+p*2][j][k-p]+s[t+1][i][j]); 
                    } 
                }
            } 
        }
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        for(int k=0;k<=W;k++)
        MAX(ans,f[T-1][i][j][k]);
        printf("%d",ans);
        return 0; 
    }
  • 相关阅读:
    希尔排序
    Java内存区域与内存溢出异常
    插入排序
    选择排序
    冒泡排序
    专利申请笔记
    Python基础指北
    mini web
    linux i/o multiplexing
    Python decorator module
  • 原文地址:https://www.cnblogs.com/dfsac/p/7587808.html
Copyright © 2020-2023  润新知