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
",ans);
    }
}


原文地址:https://www.cnblogs.com/EchoZQN/p/14594523.html