• 酱神赏花


     

    酱神去杭州赏花。

    花展在一条街道上举行,这条街道上有一共有n个节点,自左而右从1到n编号,1号和n号是左右两个端点,两个相邻端点之间的距离为1.本次花展一共要展出m朵花,在第ti时刻,有一朵颜值为bi的花将在第ai个节点展出,如果酱神在ti时刻处于第x个节点,那么他能获得的开心值为bi−|x−ai|,注意这个值可能为负。

    在t=1的时刻,酱神可以随意从1到n选出一个节点作为赏花的起点。在接下来的每个单位时间段中,酱神最多能移动d的距离。酱神每秒只能移动整数个距离,且任何时刻不能超出街道的范围。

    他能获得的最大开心值为多少?

    Input
    第一行3个数n,m,d。

    接下来m行,每行3个数ai,bi,ti。

    1≤n≤105,1≤m≤100
    1≤ai≤n
    1≤bi≤109
    1≤ti≤109
    1≤d≤109
    Output
    输出一个数,酱神的最大开心值。

    Sample Input
    30 4 2
    27 3 1
    11 4 1
    11 4 1
    1 2 20
    Sample Output
    -3

    // 显然是个dp题,dp状态很容易想到, dp[i][j] 代表在 i 位置赏前 j 朵花的最大开心度,

    将花开时间排序后

    dp[i][j] = max ( dp[i +- 开花间隙时间*d ][(j-1)&1] )

    对于这个,如果暴力的话,会超时,用单调栈优化,将找max的时间优化了,这是第一次写这个,看了思路就自己写了,用了不少时间debug。。。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define LL long long
     4 #define INF 0x3f3f3f3f3f3f3f3fll
     5 #define MX 100005
     6 struct Flo
     7 {
     8     int a,b,t;
     9     bool operator < (const Flo& b)const
    10     {
    11         return t<b.t;
    12     }
    13 }flw[MX];
    14 
    15 int n,m,d;
    16 LL dp[MX][2]; //gun dong buf
    17 int sta[MX];
    18 
    19 int main()
    20 {
    21     while (scanf("%d%d%d",&n,&m,&d)!=EOF)
    22     {
    23         for (int i=1;i<=m;i++)
    24             scanf("%d%d%d",&flw[i].a,&flw[i].b,&flw[i].t);
    25         sort(flw+1,flw+1+m);
    26 
    27         for (int i=1;i<=n;i++)
    28             dp[i][1]=flw[1].b-abs(i-flw[1].a);
    29 
    30         for (int j=2;j<=m;j++)
    31         {
    32             LL limit =(flw[j].t-flw[j-1].t)*d;
    33             int l=1,r=1;
    34             for (int k=1;k<=limit;k++)    //对于 i=1 直接先准备好单调栈
    35             {
    36                 if (k>n) break;     //这个地方搞得我 debug 很久
    37                 while (l<r&&dp[k][(j+1)&1]>=dp[sta[r-1]][(j+1)&1]) r--;
    38                 sta[r]=k; r++;
    39             }
    40             for (int i=1;i<=n;i++)
    41             {
    42                 while (l<r&&i+limit<=n&&dp[i+limit][(j+1)&1]>=dp[sta[r-1]][(j+1)&1]) r--; //尾部小的出栈
    43                 if (i+limit<=n) //进栈
    44                 {
    45                     sta[r]=i+limit;
    46                     r++;
    47                 }
    48                 while (l<r&&abs(i-sta[l])>limit) l++; //取合适的栈底元素
    49                 dp[i][j&1] = dp[sta[l]][(j+1)&1]+flw[j].b-abs(i-flw[j].a);
    50             }
    51         }
    52         LL ans = -INF;
    53         for (int i=1;i<=n;i++)
    54             ans = max (ans,dp[i][m&1]);
    55         printf("%lld
    ",ans);
    56     }
    57     return 0;
    58 }
    59 /*
    60 30 3 2
    61 27 3 1
    62 11 4 1
    63 11 4 1
    64 */
    View Code
  • 相关阅读:
    【spring源码分析】IOC容器初始化(五)
    【spring源码分析】IOC容器初始化(四)
    【spring源码分析】IOC容器初始化(三)
    【spring源码分析】IOC容器初始化(二)
    Thread.currentThread()和this的区别——《Java多线程编程核心技术》
    【spring源码分析】IOC容器初始化(一)
    【spring源码分析】准备工作
    DefaultNamespaceHandlerResolver中handlerMappings如何初始化
    SimpleDateFormat非线程安全
    MyBatis批量操作
  • 原文地址:https://www.cnblogs.com/haoabcd2010/p/6911721.html
Copyright © 2020-2023  润新知