题意:给定三种士兵G,R,P,有无限个,要求取出一个排列为n人,要求满足至少m个连续个G士兵,至多k个连续的R士兵,P士兵不作要求。求排列总数,对1000000007取模。
思路:http://blog.youkuaiyun.com/cc_again/article/details/10858813。不是很懂取模什么意思
#include<cstdio>
#include<cstdlib>
#include<time.h>
#define ll long long
const int maxn = 1000000+10;//至少m个G 至多k个R p任意
const int mod=1000000007;
ll dp[maxn][3];//[0]表示第i个为G,[1]表示R [2] 表示p
int n,m,k;
int solve(int u,int r)//代表G至多u个, R至多r个
{
for(int i=1;i<=n;i++)
{
ll sum= (dp[i-1][0]+dp[i-1][1]+dp[i-1][2])%mod;//中间结果用ll存,否则溢出
dp[i][2]=sum;
if(i<=u)
dp[i][0]=sum;
else if(i==u+1)
dp[i][0]=(sum-1)%mod;
else if(i>u+1)
dp[i][0]=(sum-dp[i-u-1][1]-dp[i-u-1][2])%mod;
if(i<=r)
dp[i][1]=sum;
else if(i==r+1)
dp[i][1]=(sum-1)%mod;
else if(i>r+1)
dp[i][1]=(sum-dp[i-r-1][0]-dp[i-r-1][2])%mod;
}
return (dp[n][0]+dp[n][1]+dp[n][2])%mod;
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
dp[0][0]=1;dp[0][1]=dp[0][2]=0;
int ans=((solve(n,k)-solve(m-1,k))%mod+mod)%mod;
printf("%d\n",ans);
}
}
本文介绍了一种使用动态规划解决特定排列组合问题的方法,该问题要求构造由三种士兵(G、R、P)组成的序列,其中G士兵需满足至少m个连续出现,R士兵则需满足至多k个连续出现,而P士兵没有限制。文章提供了完整的C++代码实现,并通过取模操作确保结果在一定范围内。
7976

被折叠的 条评论
为什么被折叠?



