碎碎念(dp)

纵然是瞬间 提交于 2020-02-14 00:39:20

题目

链接:https://ac.nowcoder.com/acm/contest/3006/F
来源:牛客网

在ACM比赛里,除了CE以外都是有效的提交。每一个提交都会有其评测的结果,或是AC,或是RJ(Rejected,包含各种不通过的情况)。往往一个人上去提交的时候,总有一个队友会坐在边上等着结果。那个人,往往都是只读题不写题的云选手~

牛牛战队里也有这样的云选手——牛能。当牛能看到有效提交得到了AC以后,都会大呼一声“你好能啊!”,反之,如果得到了RJ的话,就会化身为喷子,说xx句“你能不能行啊!”。大家比赛的都十分紧张,这样的大声呼喊未免会引起旁边队伍的注意。

当然牛牛战队交题的时候也很小心,一旦这一发出现了RJ,下一发有效提交一定能获得AC。

比赛结束了以后,旁边的一支队伍愤怒的跑过来说:你们比赛的时候吵不吵啊,一直在这大吼,吼了这么多句!

激烈的争吵引起了吃瓜群众的注意,吃瓜群众问道:吼了多少句啊,这么讨厌的吗

“啊……我也记不清了,大概是在[L,R]这个区间吧”

作为吃瓜群众的你,想根据这个信息算出,这个队伍有多少种有效提交结果序列的可能呢?

输入描述:

输入数据包括单组数据、多组询问。输入第一行包含一个整数x(2≤x≤100000),表示牛能在RJ状态下会说“你能不能行啊!”的句子数量。

第二行包括一个整数Q(1≤Q≤105^5),表示询问数量。

接下来QQ行,每行包括两个整数L,R(1≤L≤R≤100000),表示每次询问下句子的区间数。

输出描述:

对于每组数据,在一行内输出一个整数,表示牛牛战队提交结果的可能性。由于结果可能很大,请对1000000007取模。

思路

我们写状态表示dp[i][j],i代表到这个位置,j=0的时候代表选择ac, j=1的时候代表选择rj.很容易 的就写出来状态转移方程dp[i][0]=dp[i-1][1]+dp[i-1][0], dp[i][1]=dp[i-x][0],然后求一遍前缀和。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef unsigned long long ull;
const int N=1e5+7;
const int mod=1e9+7; 
ll dp[N][3],a[N],sum[N];
int main()
{
	//freopen("test.in","r",stdin);//设置 cin scanf 这些输入流都从 test.in中读取
    //freopen("test.out","w",stdout);//设置 cout printf 这些输出流都输出到 test.out里面去
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	int x;
	cin>>x;
	dp[0][0]=1;
	for(int i=1;i<N;i++)
	{
		if(i>=x)
		{
			dp[i][0]=(dp[i-1][1]+dp[i-1][0])%mod;
			dp[i][1]=dp[i-x][0]%mod;
			dp[i][2]=(dp[i][0]+dp[i][1])%mod;
		}
		else
		{
			dp[i][0]=(dp[i-1][0])%mod;
			dp[i][2]=dp[i][0];
		}
		sum[i]=(sum[i-1]+dp[i][2])%mod;	
	}
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		int x,y;
		cin>>x>>y;
		cout<<(sum[y]-sum[x-1]+mod)%mod<<endl;
	}
	return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!