杭电多校第10场 6880 Permutation Counting(DP)

2024-04-15 23:58

本文主要是介绍杭电多校第10场 6880 Permutation Counting(DP),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Problem Description
For a given permutation a1,a2,⋯,an of length n, we defined the neighbor sequence b of a, the length of which is n−1, as following:

bi={01ai<ai+1ai>ai+1
.

For example, the neighbor sequence of permutation 1,2,3,6,4,5 is 0,0,0,1,0.

Now we give you an integer n and a sequence b1,b2,⋯,bn−1 of length n−1, you should calculate the number of permutations of length n whose neighbor sequence equals to b.

To avoid calculation of big number, you should output the answer module 109+7.

Input
The first line contains one positive integer T (1≤T≤50), denoting the number of test cases. For each test case:

The first line of the input contains one integer n,(2≤n≤5000).

The second line of the input contains n−1 integer: b1,b2,⋯,bn−1

There are no more than 20 cases with n>300.

Output
For each test case:

Output one integer indicating the answer module 109+7.

Sample Input
2
3
1 0
5
1 0 0 1

Sample Output
2
11

题意:
求多少种前n个数的排列符合题目中的限制
在这里插入图片描述

思路:
定义 f [ i ] [ j ] f[i][j] f[i][j]为考虑了前 i i i个数的排列,第 i i i个位置放的数在前 i i i个数中为 j j j的小方案数。
那么如果 a [ i ] > a [ i − 1 ] , a[i]>a[i-1], a[i]>a[i1]也就是 b [ i − 1 ] = 0 b[i-1]=0 b[i1]=0
f [ i ] [ j ] = ∑ f [ i − 1 ] [ k ] , 1 ≤ k ≤ j − 1 f[i][j]=∑f[i-1][k],1≤k≤j-1 f[i][j]=f[i1][k]1kj1
j j j可以等于 k k k,因为前 i i i个数的第 j j j小一定小于前 i − 1 i-1 i1个数的第 j j j小。下面 j j j可以等于 k k k同理。

如果 a [ i ] < a [ i − 1 ] , a[i]<a[i-1], a[i]<a[i1]也就是 b [ i − 1 ] = 1 b[i-1]=1 b[i1]=1
f [ i ] [ j ] = ∑ f [ i − 1 ] [ k ] , j ≤ k ≤ i − 1 f[i][j]=∑f[i-1][k],j≤k≤i-1 f[i][j]=f[i1][k]jki1

#include <cstdio>
#include <cstring>
#include <algorithm>using namespace std;typedef long long ll;
const int maxn = 5005;
const int mod = 1e9 + 7;ll f[maxn][maxn];
int a[maxn];int main() {int T;scanf("%d",&T);while(T--) {int n;scanf("%d",&n);for(int i = 1;i <= n;i++) {for(int j = 1;j <= n;j++) {f[i][j] = 0;}}for(int i = 1;i < n;i++) scanf("%d",&a[i]);f[1][1] = 1;for(int i = 2;i <= n;i++) {ll sum = 0;if(a[i - 1] == 0) { //a[i]>a[i-1]for(int j = 1;j <= i;j++) {f[i][j] = sum;sum = (sum + f[i - 1][j]) % mod;}} else { //a[i]<a[i-1]for(int j = i - 1;j >= 1;j--) {sum = (sum + f[i - 1][j]) % mod;f[i][j] = sum;}}}ll ans = 0;for(int i = 1;i <= n;i++) {ans = (ans + f[n][i]) % mod;}printf("%lld\n",ans);}return 0;
}

这篇关于杭电多校第10场 6880 Permutation Counting(DP)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/907286

相关文章

hdu4826(三维DP)

这是一个百度之星的资格赛第四题 题目链接:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1004&cid=500 题意:从左上角的点到右上角的点,每个点只能走一遍,走的方向有三个:向上,向下,向右,求最大值。 咋一看像搜索题,先暴搜,TLE,然后剪枝,还是TLE.然后我就改方法,用DP来做,这题和普通dp相比,多个个向上

hdu1011(背包树形DP)

没有完全理解这题, m个人,攻打一个map,map的入口是1,在攻打某个结点之前要先攻打其他一个结点 dp[i][j]表示m个人攻打以第i个结点为根节点的子树得到的最优解 状态转移dp[i][ j ] = max(dp[i][j], dp[i][k]+dp[t][j-k]),其中t是i结点的子节点 代码如下: #include<iostream>#include<algorithm

hdu4865(概率DP)

题意:已知前一天和今天的天气概率,某天的天气概率和叶子的潮湿程度的概率,n天叶子的湿度,求n天最有可能的天气情况。 思路:概率DP,dp[i][j]表示第i天天气为j的概率,状态转移如下:dp[i][j] = max(dp[i][j, dp[i-1][k]*table2[k][j]*table1[j][col] )  代码如下: #include <stdio.h>#include

usaco 1.1 Broken Necklace(DP)

直接上代码 接触的第一道dp ps.大概的思路就是 先从左往右用一个数组在每个点记下蓝或黑的个数 再从右到左算一遍 最后取出最大的即可 核心语句在于: 如果 str[i] = 'r'  ,   rl[i]=rl[i-1]+1, bl[i]=0 如果 str[i] = 'b' ,  bl[i]=bl[i-1]+1, rl[i]=0 如果 str[i] = 'w',  bl[i]=b

uva 10154 DP 叠乌龟

题意: 给你几只乌龟,每只乌龟有自身的重量和力量。 每只乌龟的力量可以承受自身体重和在其上的几只乌龟的体重和内。 问最多能叠放几只乌龟。 解析: 先将乌龟按力量从小到大排列。 然后dp的时候从前往后叠,状态转移方程: dp[i][j] = dp[i - 1][j];if (dp[i - 1][j - 1] != inf && dp[i - 1][j - 1] <= t[i]

uva 10118 dP

题意: 给4列篮子,每次从某一列开始无放回拿蜡烛放入篮子里,并且篮子最多只能放5支蜡烛,数字代表蜡烛的颜色。 当拿出当前颜色的蜡烛在篮子里存在时,猪脚可以把蜡烛带回家。 问最多拿多少只蜡烛。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cs

uva 10069 DP + 大数加法

代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <cl

uva 10029 HASH + DP

题意: 给一个字典,里面有好多单词。单词可以由增加、删除、变换,变成另一个单词,问能变换的最长单词长度。 解析: HASH+dp 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#inc

XTU 1233 n个硬币连续m个正面个数(dp)

题面: Coins Problem Description: Duoxida buys a bottle of MaiDong from a vending machine and the machine give her n coins back. She places them in a line randomly showing head face or tail face o

dp算法练习题【8】

不同二叉搜索树 96. 不同的二叉搜索树 给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。 示例 1: 输入:n = 3输出:5 示例 2: 输入:n = 1输出:1 class Solution {public int numTrees(int n) {int[] dp = new int