CF 1178 F1

14 篇文章 0 订阅

题意:n个格子,编号1~n,n种颜色的油漆 ,编号1~n,每次依次选第i种颜色并将一段区间内全部涂成颜色i,区间内颜色被覆盖,可以涂色的前提是这一区间是相同的颜色,所以你可以认为最初n个格子全是白色。问有多少种涂色方式形成最终的颜色分布。

思路:笛卡尔树DP

从小到大操作,对于一个1他染的染色可能是红色的一段,所以可以分成左右两段分开考虑,最后乘起来即可。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=b;i>=a;i--)
using namespace std;
#define ll long long
const int N=3e5+5;
const int mod = 998244353;
int dp[510][510],a[510],n,m;
int sum(int a, int b) {
    int s = (a + b);
    if (s >= mod) s -= mod;
    return s;
}
int sub(int a, int b) {
    int s = a - b;
    if (s < 0) s += mod;
    return s;
}
int mult(int a, int b) {
    return (1LL * a * b) % mod;
}
ll rd()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int solve(int l,int r)
{
	if(dp[l][r]) return dp[l][r];
	if(l>=r) return 1;
	int lowi=l;
	rep(i,l+1,r) if(a[lowi]>a[i]) lowi=i;
	int totl=0,totr=0;
	rep(i,l,lowi) totl=sum(totl,mult(solve(l,i-1),solve(i,lowi-1)));
	rep(i,lowi,r) totr=sum(totr,mult(solve(lowi+1,i),solve(i+1,r)));
	return dp[l][r]=1ll*totl*totr%mod;
}
int main()
{
	n=rd();m=rd();
	rep(i,1,n) a[i]=rd();
	printf("%d\n",solve(1,n)); 
} 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值