CF 1927

G

link
定义dpijk为考虑完第i个点,最左边没有染色的点为j,最右边没有染色的点为k的最小数量。
考虑转移(用自己更新别人)
如果不用i,直接转移到dpi+1jk

如果向左喷,kmax(i+1,k),判断能喷到的位置

  • j更靠左,j将变成max(i+2,k+1)i+1的下一个或k的下一个将为最左边没有染色的);
  • 否则,j将不变。

如果向右喷,kmax(i+ai1,k),判断能喷到的位置

  • j更靠左,j将变成max(i+ai,k+1)i+ai1的下一个或k的下一个将为最左边没有染色的);
  • 否则,j将不变。
点击查看代码
#include<bits/stdc++.h>

#define int long long

using namespace std;

int t;
int n;
int a[105];
int q[105];
int h[105];
int dp[105][105][105];

void mx(int &a,int b){
	a = min(a,b);
}

void qwq(){
	
	cin >> n;
	for(int i = 1;i <= n;++ i){
		cin >> a[i];
		q[i] = max(1ll,i-a[i]+1);
		h[i] = min(n,i+a[i]-1);
	}
	
	memset(dp,0x3f,sizeof(dp));
	dp[0][1][0] = 0;
	
	for(int i = 0;i < n;++ i){
		
		for(int j = 1;j <= n+1;++ j)
			for(int k = 0;k <= n;++ k)
				mx(dp[i+1][j][k],dp[i][j][k]);
		
		for(int j = 1;j <= n+1;++ j){
			for(int k = 0;k <= n;++ k){
				if(q[i+1] <= j){
					mx(dp[i+1][max(i+2,k+1)]
					[max(i+1,k)],dp[i][j][k]+1);
				}
				else{
					mx(dp[i+1][j][max(i+1,k)],
					dp[i][j][k]+1);
				}
			}
		}
		
		for(int j = 1;j <= n+1;++ j){
			for(int k = 0;k <= n;++ k){
				if(i+1 <= j){
					mx(dp[i+1][max(h[i+1]+1,j)]
					[max(h[i+1],k)],
					dp[i][j][k]+1);
				}
				else{
					mx(dp[i+1][j][max(h[i+1],k)]
					,dp[i][j][k]+1);
				}
			}
		}
		
	}
	
	cout << dp[n][n+1][n] << endl;
	
}

signed main(){
	
	cin >> t;
	while(t--) qwq();
	
	return 0;
	
}
posted @   不认命,就是哪吒的命!  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· Trae初体验
点击右上角即可分享
微信分享提示