首页 > 代码库 > zoj3747(递推dp)
zoj3747(递推dp)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5170
题意:给n个士兵排队,每个士兵三种G、R、P可选,求至少有m个连续G士兵,最多有k个连续R士兵的排列的种数。
详细解法:http://blog.csdn.net/cc_again/article/details/24841249
注意下取模后为负的情况
#include <cstdio>#include <cstring>#include <cmath>#include <iostream>#include <algorithm>#include <queue>#include <cstdlib>#include <stack>#include <vector>#include <set>#include <map>#define LL long long#define mod 1000000007#define inf 0x3f3f3f3f#define N 1000010#define clr(a) (memset(a,0,sizeof(a)))using namespace std;LL dp[N][3];LL m,n,k;LL solve(LL u,LL v){ dp[0][0]=1;dp[0][1]=0;dp[0][2]=0; for(int i=1;i<=n;i++) { LL sum=(dp[i-1][0]+dp[i-1][1]+dp[i-1][2])%mod; dp[i][2]=sum; if(i<=u)dp[i][0]=sum; else if(i==u+1)dp[i][0]=sum-1; else dp[i][0]=(sum-dp[i-u-1][1]-dp[i-u-1][2]+mod)%mod; if(i<=v)dp[i][1]=sum; else if(i==v+1)dp[i][1]=sum-1; else dp[i][1]=(sum-dp[i-v-1][0]-dp[i-v-1][2]+mod)%mod; } return (dp[n][0]+dp[n][1]+dp[n][2])%mod;}int main(){ while(scanf("%lld%lld%lld",&n,&m,&k)>0) { printf("%lld\n",((solve(k,n)-solve(k,m-1))%mod+mod)%mod); }}
zoj3747(递推dp)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。