您的位置:首页 > 其它

Ural 2018 The Debut Album

2016-08-07 22:09 681 查看
题目链接:http://acm.timus.ru/problem.aspx?space=1&num=2018



题意:求一个含n个仅由两个不同字符组成的字符串中,第一种字符连续的数量不超过a个,第二种字符连续的数量不超过b个的字符串个数。



思路:dp,我们用f[i][j][k]表示,在第i个位置,放j类型字符时(j=0/1),且算上i位置已经连续放了k个j类型字符的方案数。

那么很明显,当k>1时,f[i][j][k] = f[i-1][j][k-1] , 当k = 1 ;  f[i][j][1] = ∑f[i-1][1-j][k] k为另一个字符全部合法的连续个数。

这个递推式是相邻的i之间的,所以可以使用滚动数组来节约空间。



#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <utility>
using namespace std;

#define rep(i,j,k) for (int i=j;i<=k;i++)
#define Rrep(i,j,k) for (int i=j;i>=k;i--)

#define Clean(x,y) memset(x,y,sizeof(x))
#define LL long long
#define ULL unsigned long long
#define inf 0x7fffffff
#define mod 1000000007
const int maxn = 309;
int n,a,b;
LL dp[2][2][maxn];

int main()
{
cin>>n>>a>>b;
Clean(dp,0);
dp[0][0][1] = dp[0][1][1] = 1;
int now,cur;
now = 0;
cur = 1;
rep(l,2,n)
{
now ^= 1;
cur ^= 1;
LL A = 0;
rep(i,1,a)
A =( A + dp[cur][0][i] ) % mod ;
LL B = 0;
rep(i,1,b)
B = ( B + dp[cur][1][i] ) % mod;
Clean(dp[now],0);
dp[now][0][1] = B;
dp[now][1][1] = A;
rep(i,1,a)
dp[now][0][i] = ( dp[now][0][i] + dp[cur][0][i-1] ) % mod;
rep(i,1,b)
dp[now][1][i] = ( dp[now][1][i] + dp[cur][1][i-1] ) % mod;
}
LL ans = 0;
rep(i,1,a) ans = ( ans + dp[now][0][i] ) % mod;
rep(i,1,b) ans = ( ans + dp[now][1][i] ) % mod;
printf("%I64d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  DP