F1. Short Colorful Strip Codeforces Global Round 4 (区间dp)

链接: http://codeforces.com/contest/1178/problem/F1
题面:
There are n+1 distinct colours in the universe, numbered 0 through n. There is a strip of paper m centimetres long initially painted with colour 0.

Alice took a brush and painted the strip using the following process. For each i from 1 to n, in this order, she picks two integers 0≤ai<bi≤m, such that the segment [ai,bi] is currently painted with a single colour, and repaints it with colour i.

Alice chose the segments in such a way that each centimetre is now painted in some colour other than 0. Formally, the segment [i−1,i] is painted with colour ci (ci≠0). Every colour other than 0 is visible on the strip.

Count the number of different pairs of sequences {ai}ni=1, {bi}ni=1 that result in this configuration.

Since this number may be large, output it modulo 998244353.

Input
The first line contains a two integers n, m (1≤n≤500, n=m) — the number of colours excluding the colour 0 and the length of the paper, respectively.

The second line contains m space separated integers c1,c2,…,cm (1≤ci≤n) — the colour visible on the segment [i−1,i] after the process ends. It is guaranteed that for all j between 1 and n there is an index k such that ck=j.

Note that since in this subtask n=m, this means that c is a permutation of integers 1 through n.

Output
Output a single integer — the number of ways Alice can perform the painting, modulo 998244353.
题意:
有个长度为m公分的布,要在上面每公分都染上颜色,整块布染恰好n(n=m)种颜色。颜色标号从1到n。染色需遵循:
1.从颜色1到颜色n依次,即必须先染标号小的颜色
2.每次可以染任意一个区间,但必须满足这个区间之前的颜色是相同的。
询问将这块布染成所给颜色的方案数。
思路:
首先附上神牛题解链接:https://www.cnblogs.com/wxyww/p/CF1178F1.html#3280520539
f [ l ] [ r ] 表 示 区 间 [ l , r ] 的 染 色 方 案 数 , g [ l ] [ r ] 表 示 将 区 间 [ l , r ] 一 开 始 染 成 区 间 最 小 颜 色 后 进 行 染 色 的 方 案 数 f[l][r]表示区间[l,r]的染色方案数,g[l][r]表示将区间[l,r]一开始染成区间最小颜色后进行染色的方案数 f[l][r][l,r]g[l][r][l,r]
g [ l ] [ r ] = f [ l ] [ k − 1 ] ∗ f [ k + 1 ] [ r ] , k 为 颜 色 最 小 的 位 置 g[l][r]=f[l][k-1]*f[k+1][r],k为颜色最小的位置 g[l][r]=f[l][k1]f[k+1][r],k
f [ l ] [ r ] = ∑ i = l r g [ l ] [ i ] ∗ f [ i + 1 ] [ r ] f[l][r]=\sum_{i=l}^{r}g[l][i]*f[i+1][r] f[l][r]=i=lrg[l][i]f[i+1][r]
最 后 所 求 答 案 为 f [ 1 ] [ n ] 最后所求答案为f[1][n] f[1][n]

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=998244353;
const int N=505;
ll f[N][N],g[N][N];
int a[N];
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	a[0]=0x3f3f3f3f;
	for(int i=1;i<=n+1;i++)
		g[i][i]=f[i][i]=f[i][i-1]=g[i][i-1]=1;
	for(int len=2;len<=n;len++)
	{
		for(int l=1;l+len-1<=n;l++)
		{
			int r=l+len-1;
			int tmp=0;
			for(int k=l;k<=r;k++)
			{
				if(a[k]<a[tmp])
					tmp=k;
			}
			g[l][r]=f[l][tmp-1]*f[tmp+1][r]%mod;
			for(int k=l;k<=r;k++)
			{
				f[l][r]=(f[l][r]+g[l][k]*f[k+1][r]%mod)%mod;
			}
		}
	}
	printf("%lld\n",f[1][n]);
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值