Number String UVA

来源:互联网 发布:想开个淘宝店 编辑:程序博客网 时间:2024/06/05 05:46

考察动态规划的一道题目,有点难。dp[i][j]代表的是当前的i个数字的排列中以j开头的符合要求的排列的个数,同时我们利用一个sum来提高后续的计算速度,sum[i][j]代表的是当前的i个数字中分别以1,2,3......j开头的符合要求的排列的总数,然后开始下面的动态规划的过程,如果当前的字符是‘I’或者‘?’,那么在i个数字中以j开头之后,剩下的i-1个数字只能以1到j-1来开头,即是sum[i-1][j-1];如果当前的字符是‘D’或者‘?’,那么在i个数字以j开头之后,剩下的数字也就只能以j+1到i来进行开头,也就是sum[i-1][i-1]-sum[i-1][j-1];每次这样计算结束之后要对sum[i][j]进行更新,也就是把当前的计算的dp[i][j]的结果以及sum[i][j-1]统计到一起,记录到sum[i][j]中,好了,废话讲了这么多,具体实现见如下代码:

#include<iostream>#include<vector>#include<string>#include<set>#include<stack>#include<queue>#include<map>#include<algorithm>#include<cmath>#include<iomanip>#include<cstring>#include<sstream>#include<cstdio>#include<deque>#include<functional>using namespace std;typedef long long LL;const int maxn = 1005;const LL mod = 1000000007;LL dp[maxn][maxn];LL sum[maxn][maxn];string s;int main(){while (cin >> s){int length = s.size()+1;memset(dp, 0, sizeof(dp));memset(sum, 0, sizeof(sum));dp[1][1] = 1;sum[1][1] = 1;for (int i = 2; i <= length; i++){for (int j = 1; j <= i; j++){dp[i][j] = 0;if (s[i - 2] == 'I' || s[i - 2] == '?'){//increasedp[i][j] = (dp[i][j] + sum[i - 1][j - 1]) % mod;}if (s[i - 2] == 'D' || s[i - 2] == '?'){//decreasedp[i][j] = (dp[i][j] + sum[i - 1][i - 1] - sum[i - 1][j - 1]) % mod;}sum[i][j] = (sum[i][j-1] + dp[i][j]) % mod;}}cout << (sum[length][length]+mod)%mod << endl;}return 0;}

原创粉丝点击