zoukankan      html  css  js  c++  java
  • [多校联考2 T3] 排列 (DP)

    DP


    Description

    对于一个排列,考虑相邻的两个元素,如果后面一个比前面一个大,表示这个位置是上升的,用 I 表示,反之这个位置是下降的,用 D表示。如排列 3,1,2,7,4,6,5 可以表示为 DIIDID。 现在给出一个长度为 n-1的排列表示,问有多少种 1 到n 的排列满足这种表示。

    Input

    一个字符串 S,S 由 I,D,?组成。?表示这个位置既可以为 I,又可以为 D

    对于 20%的数据,S 长度 ≤ 10;
    对于 100%的数据,S长度 ≤ 1000。

    Output

    有多少种排列满足上述字符串。输出排列数模 1000000007。

    Sample Input

    ?D

    Sample Output

    3


    这是一道比较裸的动态规划题目,dp[i][j]表示前 i 位数中,最后一位为第 j 大的方案数。即当转移到i时,前 i - 1 位数是1 ~ i-1 中的数。此时:

    1. 如果输入为 I,那么 j 可由 1 ~ j-1 转移过来,大于等于 j 的数都加一即可保证前 i 个数为1 ~ i;
    2. 如果输入为 D,则 j 可由 j ~ i-1 转移而来,同样,大于等于 j 的数字都加一。
    3. 如果输入为 ?,则将前两种方案加起来。

    在实际转移过程中,不用涉及到大于等于 j 的数加一,只需知道转移原理即可。

    但是如果直接这样转移当然是不行的,还需注意到,题目中 (n <= 10^3)
    转移是(n^3),会超时。所以我们可以在转移之前维护一个前缀和即可去掉一个(n)。使时间复杂度降为(n^2)。如果害怕爆空间,还可以采用滚动数组进行优化。

    Ps: 本题还有一个点需要注意,由于前缀和取了模,在算下降情况时,可能会出现负数,所以先加上一个mod再取模。
    

    至此,问题完美解决。

    代码

    #include <cstdio>
    
    int dp[2][1005];
    const int mod = 1000000007;
    
    int main() {
    	dp[0][1] = 1;
    	int cur = 0;
    	char x = getchar();
    	int i = 1;
    	while(x == 'I'||x == 'D'||x == '?') {
    		cur ^= 1;i++;
    		for(int j = 1;j < i;j++)dp[cur^1][j] += dp[cur^1][j-1],dp[cur^1][j] %= mod,dp[cur][j] = 0;
    		
    		if(x == 'I') {
    			for(int j = 2;j <= i;j++)dp[cur][j] = dp[cur^1][j-1],dp[cur][j] %= mod;
    		}
    		if(x == 'D') {
    			for(int j = 1;j < i;j++)dp[cur][j] = dp[cur^1][i-1] - dp[cur^1][j-1] + mod,dp[cur][j] %= mod;
    		}
    		if(x == '?') {
    			for(int j = 2;j <= i;j++)dp[cur][j] = dp[cur^1][j-1],dp[cur][j] %= mod;
    			for(int j = 1;j < i;j++)dp[cur][j] += dp[cur^1][i-1] - dp[cur^1][j-1] + mod,dp[cur][j] %= mod;
    		}
    		x = getchar();
    	}
    	int ans = 0;
    	for(int j = 1;j <= i;j++)ans = (ans + dp[cur][j]) % mod;
    	printf("%d",ans);
    	
    	return 0;
    } 
    
  • 相关阅读:
    Python开发环境Spyder介绍
    Python干货整理之数据结构篇
    通过Python爬虫按关键词抓取相关的新闻
    疫情后来场说走就走的旅行,Python制作一份可视化的旅行攻略
    详细介绍去一年在 PyPI 上下载次数最多的 Python 包
    Python错误与异常
    python爬虫爬取2020年中国大学排名
    微信史上最短的一行功能代码:拍一拍
    Python爬取某宝商品数据案例:100页的价格、购买人数等数据
    我的SAS菜鸟之路7
  • 原文地址:https://www.cnblogs.com/ZegWe/p/5987104.html
Copyright © 2011-2022 走看看