题目大意:给定一个元素两两不相等的目标序列,每次按照给定方式将一个元素加入到序列当中,问得到目标序列的方案有几种
题解:没有规律,考虑dp一下
因为加入的人需要和上一个人进行比较,那么记录进状态里,用
f[i][j][0/1]表示[l,r]区间,最后加入的在
l/r的方案数
转移按照题目中所说
需要注意的是
f[i][i][0]和f[i][i][1]
中只能有一个为1,不然会重复
我的收获:巧妙构思区间
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int M=1005;
#define P 19650827
int n,h[M];
int f[M][M][2];
int dfs(int l,int r,int k)
{
if(l==r) return k;
if(f[l][r][k]!=-1) return f[l][r][k];
int res=0;
if(!k) res+=dfs(l+1,r,0)*(h[l]<h[l+1])+dfs(l+1,r,1)*(h[l]<h[r]);
else res+=dfs(l,r-1,0)*(h[r]>h[l])+dfs(l,r-1,1)*(h[r]>h[r-1]);
return f[l][r][k]=res%P;
}
void work(){
memset(f,-1,sizeof(f));
printf("%d\n",(dfs(1,n,0)+dfs(1,n,1))%P);
}
void init()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&h[i]);
}
int main()
{
init();
work();
return 0;
}
本文探讨了一种通过动态规划解决特定序列构造问题的方法。针对给定的目标序列,每次按特定方式加入元素,求解得到目标序列的不同方案数量。文章详细介绍了状态定义、状态转移方程,并提供了一个具体实现示例。
235

被折叠的 条评论
为什么被折叠?



