CF1927G. Paint Charges
-
做这道题的时候自己把
式子卡的太死了,导致怎么想都想不出来,但正解的 设的是很宽松的 -
设
表示考虑前 个数,所有中第一个没被染色的是 ,在 后面第一个没被染到的是 -
转移就判断第
个数向左向右还是不选即可 -
-
这个题还可以
,而且和 的式子好像几乎没什么关系 -
设
表示让 染上颜色的最少操作次数 -
发现有三种可能:
-
让
向左边染色, -
让
向右边染色覆盖过 , -
让
向右覆盖过 ,在 中找一点 向左覆盖过 ,转移挺难写的略
-
-
直接转移即可,第三种要通过改变枚举顺序简单优化一下
-
复杂度
#include<bits/stdc++.h>
#define ll long long
#define ckmin(a, b) (a = min(a, b))
#define ckmax(a, b) (a = max(a, b))
#define pcn putchar('\n');
using namespace std;
template<typename T>T &read(T &x){
cin >> x;
return x;
}
const int maxn = 150;
int n, l[maxn], r[maxn];
int dp[maxn];
void mian(int TwT){
read(n);
int a;
for(int i = 1; i <= n; ++ i){
read(a);
l[i] = max(i - a + 1, 1);
r[i] = min(i + a - 1, n);
}
for(int i = 1; i <= n; ++ i){
dp[i] = n + 5;
}
dp[0] = 0;
for(int i = 1; i <= n; ++ i){
for(int j = l[i]; j <= i; ++ j){
ckmin(dp[i], dp[j - 1] + 1);
}
for(int j = 1; j <= i; ++ j){
if(r[j] < i) continue;
ckmin(dp[i], dp[j - 1] + 1);
}
int L = i + 1, R = i, x = i;
for(int j = i - 1; j >= 1; -- j){
if(r[j] < i) continue;
R = min(L - 1, j);
for(; x > j; -- x){
if(l[x] > j) continue;
ckmin(L, l[x]);
}
for(int k = L; k <= R; ++ k){
ckmin(dp[i], dp[k - 1] + 2);
}
}
}
// for(int i = 1; i <= n; ++ i){
// printf("%d ", dp[i]);
// }
// pcn;
printf("%d\n", dp[n]);
}
void init(int TwT){
}
int main(){
int T = 1;
read(T);
for(int TwT = 1; TwT <= T; ++ TwT){
init(TwT);
mian(TwT);
}
return 0;
}
/*
1
2
2 1
*/
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析