• loj 10180 烽火传递


    题目

    分析

    考虑DP,

    需要的状态:位置,自己是否发信号

    f[i][0/1]表示覆盖到第i台的最少代价

    也就是说,只保证了结尾为i及小于i的区间有烽火台

    转移:

    f[i][0] = min(f[i-m+1][1],f[i-m+2][1],…,f[i-1][1]);

    f[i][1] = min(f[i-m][1],f[i-m+1][1],f[i-m+2][1],…,f[i-1][1]);

    f[i][1]不能用f[j][0]转移

    因为只保证了结尾为i - m + 1及小于i - m + 1的区间有烽火台,而不能保证以 i - m + 1到 i 为结尾的区间有烽火台

    好了

    接下来,看数据范围

    显然不可能暴枚

    看,固定区间的最值,

    单调队列

    代码

     1 /************************
     2 User:Mandy.H.Y
     3 Language:c++
     4 Problem:luogu
     5 Algorithm:
     6 Date:2019.9.2 
     7 ************************/
     8 #include<bits/stdc++.h>
     9 
    10 using namespace std;
    11 
    12 const int maxn = 2e5 + 5;
    13 
    14 int n,m,l1,r1;
    15 int a[maxn],f[maxn][3];
    16 int q1[maxn];
    17 
    18 template<class T>inline void read(T &x){
    19     x = 0;bool flag = 0;char ch = getchar();
    20     while(!isdigit(ch)) flag |= ch == '-',ch = getchar();
    21     while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar();
    22     if(flag) x = -x;
    23 }
    24 
    25 template<class T>void putch(const T x){
    26     if(x > 9) putch(x / 10);
    27     putchar(x % 10 | 48);
    28 }
    29 
    30 template<class T>void put(const T x){
    31     if(x < 0) putchar('-'),putch(-x);
    32     else putch(x);
    33 }
    34 
    35 void file(){
    36     freopen("10180.in","r",stdin);
    37     freopen("10180.out","w",stdout);
    38 }
    39 
    40 void readdata(){
    41     read(n);read(m);
    42     for(int i = 1;i <= n; ++ i){
    43         read(a[i]);
    44     }
    45 }
    46 
    47 void work(){
    48     
    49     f[1][0] = 0x3f3f3f3f;
    50     f[1][1] = a[1];//关于1的初始化 
    51     q1[r1++] = 1;
    52     
    53     for(int i = 2;i <= n;i ++){
    54 
    55         f[i][0] = 0x3f3f3f3f;
    56         if(i <= m) f[i][1] = a[i];//开始还没到m的 
    57         else f[i][1] = 0x3f3f3f3f;
    58 
    59         while(l1 < r1 && q1[l1] <= i - m) l1++;
    60         
    61         if(i-m > 0) f[i][1] = min(f[i-m][1] + a[i],f[i][1]);
    62         if(l1 < r1) f[i][0] = f[q1[l1]][1],f[i][1] = min(f[i][1],f[q1[l1]][1] + a[i]);
    63 
    64         while(l1 < r1 && f[i][1] <= f[q1[r1-1]][1]) r1--; 
    65         
    66         q1[r1++] = i;
    67 
    68     }
    69     
    70     put(min(f[n][1],f[n][0]));
    71 }
    72 
    73 int main(){
    74 //    file();
    75     readdata();
    76     work();
    77     return 0;
    78 }
    View Code
    非做顽石不可,哪管他敬仰暗唾
  • 相关阅读:
    ubuntu配置jdk和tomcat+部署java项目[最佳实践]
    jQuery TreeGrid
    关于json的一些误解
    jQuery2.0.3源码分析-1(持续更新中......)
    webstrom一些常用快捷键
    js插件-Map插件
    webstorm-删除项目
    随笔-20131209
    软件开发模式对比(瀑布、迭代、螺旋、敏捷)
    javascript学习(10)——[知识储备]链式调用
  • 原文地址:https://www.cnblogs.com/Mandy-H-Y/p/11447760.html
Copyright © 2020-2023  润新知