• By Elevator or Stairs CF-1249E(dp)


    题意:

    给定整数$c$和数组$a$,$b$。$a_i$表示通过爬楼梯的方法从第$i$层到$i+1$层需要的时间,$b_i$表示通过坐电梯的方法从第$i$层到$i+1$层需要的时间,坐电梯前需要等$c$单位时间,求从第一层到各层的时间。

    思路:

    $dp[i]=minleftlbrace dp[j]+sum_{k=j+1}^{i}{a[k]},dp[j]+sum_{k=j+1}^{i}{b[k]}+c ight brace$ (复杂度 $O_n$)

    $ dp[i]=minleftlbrace dp[j]+sum_a[i]-sum_a[j] , dp[j]+sum_b[i]-sum_b[j]+c ight brace $

    $dp[i]=minleftlbrace (dp[j]-sum_a[j])+sum_a[i],(dp[j]-sum_b[j])+sum_b[i]+c ight brace$

    处理出 $dp[j]-sum_a[j]$ ,$dp[j]-sum_b[j]$ 的最小值,复杂度缩小成 $O_n$

    代码:

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 const int maxn=2e5+10;
     5 const int inf=0x3f3f3f3f;
     6 
     7 int a[maxn],b[maxn];
     8 int sum1[maxn],sum2[maxn];
     9 int dp[maxn];
    10 
    11 int main()
    12 {
    13     int n,c;
    14     scanf("%d %d",&n,&c);
    15     memset(dp,inf,sizeof dp);
    16     for(int i=2;i<=n;++i) scanf("%d",&a[i]),sum1[i]=sum1[i-1]+a[i];
    17     for(int i=2;i<=n;++i) scanf("%d",&b[i]),sum2[i]=sum2[i-1]+b[i];
    18     dp[1]=min(a[1],b[1]+c);
    19     int ans1=dp[1]-sum1[1],ans2=dp[1]-sum2[1];
    20     for(int i=2;i<=n;++i)
    21     {
    22         dp[i]=min(ans1+sum1[i],ans2+sum2[i]+c);
    23         ans1=min(ans1,dp[i]-sum1[i]);
    24         ans2=min(ans2,dp[i]-sum2[i]);
    25     }
    26     for(int i=1;i<=n;++i)
    27     {
    28         if(i!=1)printf(" ");
    29         printf("%d",dp[i]);
    30     }
    31     printf("
    ");
    32 }

     

  • 相关阅读:
    做题记录
    关于有向图强连通分量的一点想法
    浅谈二分图匹配(未完)
    水题狂欢赛 (爬楼梯赛)题解(偏向自我反省)
    浅谈迭代加深(iddfs)
    浅谈单调队列优化
    [cqbzoj#10644]鱼肉炸弹题解
    树形背包[2/ 50] luogu [P1273]
    树形背包[1/ 50] luogu [P2015] (超级板)
    (树状数组)区间修改,区间查询
  • 原文地址:https://www.cnblogs.com/zhang-Kelly/p/12597029.html
Copyright © 2020-2023  润新知