题目链接:http://codeforces.com/problemset/problem/1221/D
题意:使得连续的篱笆高度不同,要求最小价值改变。
由题意可以知道最多改变的的高度为2,比方说:2 2 2,只需加一,比方说:2 2 3 我增加中间的花费最少,增加2。
这么就可以用dp的方法储存计算,dp[i][j]指的是前i个合格的第i个增加高度为j的总价值,height[i]表示增加i的高度。
具体直接看代码吧。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<cmath>
#include<string>
#include<stack>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
struct A {
ll lon,val;
}a[300100];
ll dp[300100][5];
int main()
{
int q;
scanf("%d",&q);
while(q--)
{
ll height[5];
ll ans;
int n,i,j;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%I64d %I64d",&a[i].lon,&a[i].val);
}
dp[1][0]=0;
dp[1][1]=a[1].val;
dp[1][2]=a[1].val*2;
height[0]=a[1].lon;
height[1]=a[1].lon+1;
height[2]=a[1].lon+2;
for(i=2;i<=n;i++)
{
dp[i][0]=dp[i][1]=dp[i][2]=1e18+1;
for(j=0;j<3;j++)
{
//等于的话就没有必要增加了
if(height[j]!=a[i].lon)//增加不等于第i快板子的高度就进行min计算一波最小值
{
dp[i][0]=min(dp[i][0],dp[i-1][j]);
}
}
for(j=0;j<3;j++)
{
if(height[j]!=a[i].lon+1)
{
dp[i][1]=min(dp[i][1],a[i].val+dp[i-1][j]);
}
}
for(j=0;j<3;j++)
{
if(height[j]!=a[i].val+2)
{
dp[i][2]=min(dp[i][2],a[i].val*2+dp[i-1][j]);
}
}
for(j=0;j<3;j++)
{
height[j]=a[i].lon+j;
}
}
ans=min(dp[n][0],dp[n][1]);
ans=min(ans,dp[n][2]);
printf("%I64d\n",ans);
}
return 0;
}