By Elevator or Stairs CF-1249E(dp)

题意:

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

思路:

$dp[i]=min\left\lbrace\ dp[j]+\sum_{k=j+1}^{i}{a[k]},dp[j]+\sum_{k=j+1}^{i}{b[k]}+c\right\rbrace$ (复杂度 $O_n$)

$ dp[i]=min\left\lbrace dp[j]+sum_a[i]-sum_a[j] , dp[j]+sum_b[i]-sum_b[j]+c\right\rbrace $

$dp[i]=min\left\lbrace (dp[j]-sum_a[j])+sum_a[i],(dp[j]-sum_b[j])+sum_b[i]+c\right\rbrace$

处理出 $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("\n");
32 }

猜你喜欢

转载自www.cnblogs.com/zhang-Kelly/p/12597029.html