234F fence (DP)

来源:互联网 发布:大家坛珠宝淘宝店 编辑:程序博客网 时间:2024/06/07 05:46

题目传送门

题目大意:给一个条形图涂色,每一列都是由边长为1的正方形组成。每一次将一列涂成红色或者绿色。涂成红色、绿色的正方形个数不超过a、b。当相邻两列颜色不同时,取较小者的高度作为权值。求最小权值。


设dp[i][j][0]表示将第i列涂成红色后,红色数量为j时的最小权值。

  dp[i][j][1]表示将第i列涂成绿色后,红色数量为j时的最小权值。

#include<bits/stdc++.h>using namespace std;#define inf 0x3f3f3f3fint sum[201],dp[201][40001][2];int main(){    int i,j,n,a,b;    freopen("input.txt","r",stdin);   freopen("output.txt","w",stdout);    scanf("%d%d%d",&n,&a,&b);    memset(dp,inf,sizeof(dp));    sum[0]=dp[0][0][0]=dp[0][0][1]=0;    for(i=1;i<=n;++i)    {        scanf("%d",&sum[i]);        sum[i]+=sum[i-1];    }    for(i=0;i<n;++i)        for(j=0;j<=a;++j)        {                if(sum[i+1]-j<=b) dp[i+1][j][1]=min(min(dp[i+1][j][1],dp[i][j][1]),dp[i][j][0]+min(sum[i]-sum[i-1],sum[i+1]-sum[i]));                if(j+sum[i+1]-sum[i]<=a) dp[i+1][j+sum[i+1]-sum[i]][0]=min(min(dp[i+1][j+sum[i+1]-sum[i]][0],dp[i][j][0]),dp[i][j][1]+min(sum[i]-sum[i-1],sum[i+1]-sum[i]));        }    int ans=inf;    for(i=0;i<=a;++i)    {        ans=min(ans,dp[n][i][0]);        ans=min(ans,dp[n][i][1]);    }    if(ans!=inf) printf("%d\n",ans);    else puts("-1");    return 0;}



0 0
原创粉丝点击