zoukankan      html  css  js  c++  java
  • 暑假集训Day29 H (双指针DP)

    题目链接在这里:Problem - H - Codeforces

    双指针DP其实就像一个长度可变的滑动窗口,首先因为每一个打折卡都是限定时间和租赁数量的,所以我们把要租的车全部弄开,根据租赁时间从小到大排序,f[i]表示租前i辆车至少要花多少钱,很明显f[i]是递增的,每一次的初始决策是根本不用折扣卡f[i]=f[i-1]+r,然后用折扣卡的话很显然要用一个最小的f[k]来加上c[j],这里k表示能让第j张卡有效的最前面位置,为了不让每次都从头来找这个k,我们用la[j]来存第j张卡上次用的最后位置,这样直接从上一次用的位置往后枚举就行了。

    双指针用与n次具有单调性的查找

     1 #include "bits/stdc++.h"
     2 using namespace std;
     3 typedef long long LL;
     4 const int MAX=6e5+5;
     5 LL n,m,r;
     6 struct Node{
     7     LL d,k,c;
     8 }dc[505];
     9 LL sta[MAX];
    10 LL f[MAX],la[505];
    11 int main(){
    12     freopen ("h.in","r",stdin);
    13     freopen ("h.out","w",stdout);
    14     LL i,j,p,q;
    15     scanf("%lld%lld%lld",&n,&m,&r);
    16     for (i=1;i<=n;i++){
    17         scanf("%lld%lld%lld",&dc[i].d,&dc[i].k,&dc[i].c);
    18         la[i]=1;
    19     }
    20     sta[0]=0;
    21     for (i=1;i<=m;i++){
    22         scanf("%lld%lld",&p,&q);
    23         while (q--){sta[++sta[0]]=p;}
    24     }
    25     sort(sta+1,sta+sta[0]+1);
    26     memset(f,0,sizeof(f));
    27     for (i=1;i<=sta[0];i++){
    28         f[i]=f[i-1]+r;
    29         for (j=1;j<=n;j++){
    30             while (sta[la[j]]+dc[j].d-1<sta[i] || la[j]+dc[j].k-1<i) la[j]++;
    31             f[i]=min(f[i],f[la[j]-1]+dc[j].c);
    32         }
    33     }
    34     printf("%lld",f[sta[0]]);
    35     return 0;
    36 }
    未来是什么样,未来会发生什么,谁也不知道。 但是我知道, 起码从今天开始努力, 肯定比从明天开始努力, 要快一天实现梦想。 千里之行,始于足下! ——《那年那兔那些事儿》
  • 相关阅读:
    序言vue.js介绍
    python中end=''
    python文件的操作
    python异常
    python异常(理论知识)
    Uva 11300 Spreading the Wealth 中位数
    反转(开关问题) poj3276
    NEKO's Maze Game 思维
    Aaronson 一道思维题
    我开博客了
  • 原文地址:https://www.cnblogs.com/keximeiruguo/p/15227377.html
Copyright © 2011-2022 走看看