Codeforces - Hills

题目链接:Codeforces - Hills


dp[i][j][0/1] 分别代表前 i 个,选 j 个,第 i 个是否选择的最大值。

显然选择是不能连续的,因为相邻的是一个偏序关系。

所以我们考虑当前第 i 个是否选择,取min即可。

如果当前不选的话,从 i-1 是否选择的 min考虑即可。
如果当前要选,那么我们从 i-2 是否选择来考虑。


AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include
//#define int long long
using namespace std;
const int N=5e3+10;
int n,a[N],dp[N][N][2];
signed main(){
     
	cin>>n; memset(dp,0x3f,sizeof dp);
	for(int i=1;i<=n;i++) cin>>a[i]; a[0]=1e9;
	if(n==1) return puts("0"),0;
	dp[0][0][0]=dp[1][1][1]=dp[1][0][0]=0;
	for(int i=2;i<=n;i++){
     
		dp[i][0][0]=0;
		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++) cout<<min(dp[n][i][0],dp[n][i][1])<<' ';
	return 0;
}

你可能感兴趣的:(动态规划,Codeforces,思维题)