D. Make The Fence Great Again dp

D. Make The Fence Great Again dp

题目大意:

T组输入,每次给你第 \(i\) 个篱笆的高度 \(a_i\),你每增高一厘米的花费是 \(b_i\) ,问你经过最少多少的花费使得 \(a_{i-1}!=a_i(i>1)\)

题解:

这个题目之前有同学在面试题中碰到过。容易发现,对于每一个你最多增加 2 厘米即可,因为最多左右两个你都不动,增高中间这个两厘米最优。

所以容易得到 \(dp[i][j]\) 表示前面 \(i\) 个,第 \(i\) 增高 \(j\) 厘米的最小代价。

#include <bits/stdc++.h>
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn = 3e5 + 7;
typedef long long ll;
int a[maxn],b[maxn];
ll dp[maxn][5];
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);
        for(int i=0;i<=n;i++) memset(dp[i],inf64,sizeof(dp[i]));
        dp[1][0] = 0,dp[1][1] = b[1],dp[1][2] = 2*b[1];
        for(int i=2;i<=n;i++){
            for(int j=0;j<=2;j++){
                for(int k=0;k<=2;k++){
                    if(a[i]+k==a[i-1]+j) continue;
                    dp[i][k] = min(dp[i][k],dp[i-1][j]+1ll*k*b[i]);
                }
            }
        }
        ll ans = inf64;
        for(int i=0;i<=2;i++) ans = min(ans,dp[n][i]);
        printf("%lld\n",ans);
    }
}


posted @ 2021-03-29 21:52  EchoZQN  阅读(34)  评论(0编辑  收藏  举报