题意:由数字1到n组成的所有排列中,问满足题目所给的n-1个字符的排列有多少个,如果第i字符是‘I’表示排列中的第i-1个数是小于第i个数的。

如果是‘D’,则反之。

析:dp[i][j] 表示前 i 个数以 j 结尾有多少个,然后如果是 I ,那么就好,就是 i-1 中的前j-1项和,如果是 D,那就更好玩了,我们看这样一个性质,奇妙!

假设你有一个排列是 1 3 4 ,然后下一个数是 2,那么怎么放呢,我们把 排列中每一个大于等于 2的都加1,并不会影响这个排列,然后再把这个2放上,

因为我们可以得到 dp[i][j] = dp[i-1][i-1] + dp[i-1][i-2] + ... + dp[i-1][j],这个我们可以用前缀和来优化 sum[i][j] 表示前 i 个结尾小于等于 j有总和。

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
//#include <tr1/unordered_map>
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std;
//using namespace std :: tr1; typedef long long LL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 1e3 + 5;
const int mod = 1e9 + 7;
const int N = 1e6 + 5;
const int dr[] = {-1, 0, 1, 0, 1, 1, -1, -1};
const int dc[] = {0, 1, 0, -1, 1, -1, 1, -1};
const char *Hex[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
inline LL gcd(LL a, LL b){ return b == 0 ? a : gcd(b, a%b); }
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline int Min(int a, int b){ return a < b ? a : b; }
inline int Max(int a, int b){ return a > b ? a : b; }
inline LL Min(LL a, LL b){ return a < b ? a : b; }
inline LL Max(LL a, LL b){ return a > b ? a : b; }
inline bool is_in(int r, int c){
return r >= 0 && r < n && c >= 0 && c < m;
}
int dp[maxn][maxn], sum[maxn][maxn];
char s[maxn]; int main(){
while(scanf("%s", s) == 1){
n = strlen(s);
sum[1][0] = sum[0][0] = 0;
sum[1][1] = dp[1][1] = 1;
for(int i = 2; i <= n+1; ++i){
for(int j = 1; j <= i; ++j){
if(s[i-2] == 'I') dp[i][j] = sum[i-1][j-1];
else if(s[i-2] == 'D') dp[i][j] = (sum[i-1][i-1] - sum[i-1][j-1] + mod) % mod;
else dp[i][j] = sum[i-1][i-1];
sum[i][j] = (sum[i][j-1] + dp[i][j]) % mod;
}
}
printf("%d\n", sum[n+1][n+1]);
}
return 0;
}

HDU 4055 Number String (计数DP)的更多相关文章

  1. hdu 4055 Number String (基础dp)

    Number String Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  2. hdu 4055 Number String(dp)

    Problem Description The signature of a permutation is a string that is computed as follows: for each ...

  3. HDU 4055 Number String dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4055 Number String Time Limit: 10000/5000 MS (Java/O ...

  4. hdu 4055 Number String(有点思维的DP)

    Number String Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  5. hdu 4055 Number String

    Number String http://acm.hdu.edu.cn/showproblem.php?pid=4055 Time Limit: 10000/5000 MS (Java/Others) ...

  6. HDU 4055 Number String(DP计数)

    题意: 给你一个含n个字符的字符串,字符为'D'时表示小于号,字符为“I”时表示大于号,字符为“?”时表示大小于都可以.比如排列 {3, 1, 2, 7, 4, 6, 5} 表示为字符串 DIIDID ...

  7. HDU 4055 Number String:前缀和优化dp【增长趋势——处理重复选数】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4055 题意: 给你一个由'I', 'D', '?'组成的字符串,长度为n,代表了一个1~n+1的排列中 ...

  8. hdu 4055 Number String(递推DP)

    给一个只含‘I','D','?'三种字符的字符串,I表示当前数字大于前面的数字,D表示当前的数字小于前面一位的数字,?表示当前位既可以小于又可以大于. 问1~n的排列中有多少个满足该字符串. http ...

  9. HDU 4054 Number String

    HDU 4054 Number String 思路: 状态:dp[i][j]表示以j结尾i的排列 状态转移: 如果s[i - 1]是' I ',那么dp[i][j] = dp[i-1][j-1] + ...

随机推荐

  1. eclipse安装使用注意点

    1.eclipse tomcat集成找不到server http://blog.csdn.net/wugangsunny/article/details/25246565 2.Eclipse java ...

  2. Configuring Transitive IPMP on Solaris 11

    http://www.tokiwinter.com/configuring-transitive-ipmp-on-solaris-11/ We all know the pain of configu ...

  3. ROS 禁止公网暴力破解SSH FTP

    最简单的彻底禁止公网访问SSH FTP端口 1 2 /ip firewall filter add chain=input protocol=tcp dst-port=21-22 src-addres ...

  4. ios学习--详解IPhone动画效果类型及实现方法

    详解IPhone动画效果类型及实现方法是本文要介绍的内容,主要介绍了iphone中动画的实现方法,不多说,我们一起来看内容. 实现iphone漂亮的动画效果主要有两种方法,一种是UIView层面的,一 ...

  5. Java中的class为什么要设置访问控制?和C++比较的感悟

    Java中的class为什么要设置访问控制?和C++比较的感悟 在Java中package解决了class的名字空间问题,class的成员都有各自的访问控制符,而class还有两种访问控制符,分别是p ...

  6. 使用JavaScript弹出Confirm对话框

    方法1: 这个比较简单,一句话: <a href="error.htm" onclick="javascript:return confirm('are you s ...

  7. 前端开发之JavaScript HTML DOM实战篇

    实战案例一: “灯泡发光” <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...

  8. manta api

    Authentication 有几个访问方法. 验证对服务的请求的主要方法是使用TLS上的HTTP签名. 在大多数情况下,您只需使用SSH私钥对HTTP Date标头的小写日期:和值进行签名; 这样做 ...

  9. EntityFramework - Code First - 数据迁移

    需求 在更新模型之后同步更新数据库里的表,并不丢失原有数据 使用默认值填充新增加的字段 EntityFramework迁移命令 Enable-Migrations 启用迁移 Add-Migration ...

  10. EntityFramework 学习资料

    1.EF框架step by step 2.Entity Framework Code First 学习日记 3.[译著]Code First :使用Entity. Framework编程 4.Enti ...