zoukankan      html  css  js  c++  java
  • CF1012C Solution

    题目链接

    题解

    这是一道dp题。

    状态:(dp[i][j][k])表示前(i)座山上建(j)栋房子,第(i)座山上建/不建((k=1/0))时的最小花费((k=1)时不考虑(a_{i+1}ge a_i)的花费)。

    转移方程:

    [ dp[i][j][0]=min(dp[i-1][j][0],dp[i-1][j][1]+max(0,a[i]-a[i-1]+1)); ]

    (a_i)不建房时,需要讨论(a_{i-1})上是否有房子。如果没有直接转移,有的话需加上(a_ige a_{i-1})的高度。因为也有(a_i<a_{i-1})的可能,因此需要(max(0,高度))

    [dp[i][j][1]=min(dp[i-2][j-1][0]+max(0,a[i-1]-a[i]+1),\dp[i-2][j-1][1]+max(0,a[i-1]-min(a[i-2],a[i])+1)); ]

    (a_i)建房时,(a_{i-1})上只可没有房子,需要讨论(a_{i-2})上有无房屋。如果没有需加上(a_{i-1}ge a_i)的高度,如果有则(a_{i-1})需同时低于(a_i,a_{i-2}),因此加上(a_{i-1}ge min(a_i,a_{i-2}))的高度。

    初始值:因为方程为取(min),初始值需赋极大值,而(dp[i][0][0])也参与转移,需赋值(0)。此外状态(dp[1][1][1])的花费也是(0),需要单独赋值。

    答案:(min(dp[n][i][0],dp[n][i][1]),quad 1le ile lfloor frac{n+1}{2} floor)

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N=5010;
    int a[N],dp[N][N][2];
    int main()
    {
    	int n,st;
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    	memset(dp,0x3f,sizeof(dp));
    	for(int i=0;i<=n;i++) dp[i][0][0]=0;
    	dp[1][1][1]=0; 
    	for(int i=2;i<=n;i++)
    	{
    		for(int j=1;j<=(i+1)/2;j++)
    		{
    			dp[i][j][0]=min(dp[i-1][j][0],dp[i-1][j][1]+max(0,a[i]-a[i-1]+1));
    			dp[i][j][1]=min(dp[i-2][j-1][0]+max(0,a[i-1]-a[i]+1),dp[i-2][j-1][1]+max(0,a[i-1]-min(a[i-2],a[i])+1));
    		}
    	}
    	for(int i=1;i<=(n+1)/2;i++) printf("%d ",min(dp[n][i][0],dp[n][i][1]));
    	return 0;
    }
    
  • 相关阅读:
    Java程序员必备后台前端框架--Layui【从入门到实战】(一)
    Java程序员必备后台前端框架--Layui【从入门到实战】(三)
    Java程序员必备后台前端框架--Layui【从入门到实战】(二)
    机器学习平台和深度学习平台
    python资源
    Wireshark使用入门(转)
    xxxxxxxxxxxxxxxxxxx
    大众字体
    起点字体
    pycharm调试技巧
  • 原文地址:https://www.cnblogs.com/violetholmes/p/14340933.html
Copyright © 2011-2022 走看看