• 【DP专题】——洛谷P0170道路游戏


    动规题。

    传送门:GO


    首先处理出前缀和。

    s[i][j]表示时间为i时,在j点的金币前缀和,这个更新是沿着对角线来的。

    假如机器人在第t秒,第j个位置上,下一次一定是(t+1,(j+1)%n)

    设f[i][j]表示以上情况下的最大金币量,枚举行走步数,大致口胡得到:

    f[i][j]=max(f[i][j],f[(i-k+n)%n][j-k]+s[(i-k+n)%n][k])

    但是发现枚举的东西很多(位置,时间,跳跃步长),时间复杂度O(n^3)

    所以可以不要第一维,因为p<=m,所以每次前进不会超过一圈,也就是更新某个位置的状态时,不会有后效性。

    用f[i]表示时间为i时,能获得的最大金币量。

    如果在某个位置j放了机器人,行走步长为k,修理机器人的钱用fix[i]表示,那么状态转移就是:

    f[i]=max(f[i-k]-sum[i-k][j-k]-fix[j-k])+sum[i][j]

    括号里的一坨用单调队列搞一下,取最大值即可。

    (为什么普及组的题会考单调队列,wsl)

    膜拜一下这位大大的题解:GO

     花了好久才看懂,但确实受益很多了。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int read(){
     4     int f=1,x=0;
     5     char c=getchar();
     6     while(!isdigit(c)){
     7         if(c=='-') f=-1;
     8         c=getchar();
     9     }
    10     while(isdigit(c)){
    11         x=(x<<1)+(x<<3)+(c^48);
    12         c=getchar();
    13     }
    14     return x*f;
    15 }
    16 const int N=1010;
    17 int n,m,p;
    18 int a[N][N];
    19 int sum[N][N];
    20 int fix[N];
    21 int f[N];
    22 struct node{
    23     int val,idx;
    24 };
    25 deque<node> t[N];
    26 int main(){
    27     n=read();m=read();p=read();
    28     for(int i=1;i<=n;i++){
    29         for(int j=1;j<=m;j++){
    30             a[j][i]=read();    
    31         }
    32     }
    33     int j_=1;
    34     for(int i=1;i<=m;i++){
    35         for(int j=1;j<=n;j++){
    36             if(j>1) j_=(j_==n?1:j_+1);
    37             sum[i][j_]=sum[i-1][j_]+a[i][j];
    38         }
    39     }
    40     for(int i=1;i<=n;i++){
    41         fix[i]=read();
    42     } 
    43     node tmp;
    44     j_=1;
    45     int maxlas=0;
    46     for(int i=1;i<=m;i++){
    47         tmp.idx=i;
    48         for(int j=1;j<=n;j++){
    49             if(j>1) j_=(j_==n?1:j_+1);
    50             while(!t[j_].empty()&&t[j_].front().idx+p<=i) t[j_].pop_front();
    51             tmp.val=maxlas-fix[j]+a[i][j];
    52             while(!t[j_].empty()&&tmp.val>=t[j_].back().val+sum[i][j_]-sum[t[j_].back().idx][j_]) t[j_].pop_back();
    53             t[j_].push_back(tmp);
    54             f[j]=max(maxlas-fix[j]+a[i][j],t[j_].front().val+sum[i][j_]-sum[t[j_].front().idx][j_]);
    55         }
    56         maxlas=-1e9;
    57         for(int j=1;j<=n;j++) maxlas=max(maxlas,f[j]);
    58     }
    59     printf("%d",maxlas);
    60     return 0;
    61 } 
    ——抓住了时间,却不会利用的人,终究也逃不过失败的命运。
  • 相关阅读:
    php 经验之谈
    3)nginx的启动与停止、重启,linux配置对外端口
    git 的使用
    mysql基本定义--数据类型
    Web安全XSS
    SQL优化 csdn
    数据库隔离级别
    Web前段优化,提高加载速度 css
    jquery的height()和javascript的height总结,js获取屏幕高度
    highcharts笔记 highcharts学习 highcharts用法
  • 原文地址:https://www.cnblogs.com/Nelson992770019/p/11582259.html
Copyright © 2020-2023  润新知