(The 13th Blue Bridge Cup Provincial Competition) I: Li Bai's Wine Enhanced Edition (Dynamic Programming)

output answer modulo 1e9+7

sample input

5 10

Sample output

14

Analysis: This is a dynamic programming problem. Let f[i][j][k] mean that it has reached the i-th position, encountered j flowers, and has k number of legal solutions left .

The initialization is very simple f[0][0][2]=1 , because the number of wines is 2 at the beginning

If we encounter the store n times in total and the flower m times:

Then the answer is f[n+m-1][m-1][1] , which is easy to understand, because we need to encounter m flowers in total and the last one must be a flower, then go to the penultimate one At the position, m-1 flowers must have been encountered, and since the number of wines will be reduced by 1 after encountering flowers, the number of wines must also be 1 when reaching the penultimate position.

Let's start the derivation of the state transition equation:

First of all, it is necessary for us to discuss the parity of wine, because when the number of wine is even when we reach the i-th position, the i-th position cannot be a store, because whether it is an odd or even number, the number obtained by multiplying by 2 It is an even number, so only when k is an even number can the i-th position be a store. If the i-th position is a store, then the number of wines at the i-1-th position at this time is k/2, and if the i-th position is a store The number of flowers to the i-1th position is the same as j, which is easy to understand. Let's take a look at the situation where the i-th position is a flower, then the number of wines in the i-1th position must be k. +1, because 1 is spent at the i-th position, and the number of flowers encountered at the i-th position is 1 more than the number of flowers encountered at the i-1-th position, because we are now assuming the i-th position A location is a flower.

This is the entire analysis process of this topic. The code is given below:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<set>
#include<vector>
#include<map>
#include<queue>
using namespace std;
const int N=113;
const int mod=1e9+7;
long long f[N*2][N][N];//f[i][j][k]表示走到了第i个位置,遇到了j个花,还剩k斗酒的合法方案数 
int main()
{
	f[0][0][2]=1;//初始化
	int n,m;
	cin>>n>>m;
	for(int i=1;i<n+m;i++)
	for(int j=0;j<m;j++)
	for(int k=0;k<=m;k++)//酒的数量不能超过花的数量,否则就算之后一直是花也喝不完 
	{
		if(!(k&1))//k是偶数,则第i个位置可以是店,否则不可以是店
			f[i][j][k]=(f[i][j][k]+f[i-1][j][k>>1])%mod;
		if(j>=1)//无论k是奇数还是偶数,第i个位置都可以是花 
			f[i][j][k]=(f[i][j][k]+f[i-1][j-1][k+1])%mod;
	}
	printf("%lld",f[n+m-1][m-1][1]);
	return 0; 
}

Guess you like

Origin blog.csdn.net/AC__dream/article/details/124072351