给出一个暴力的方法
#include<stdio.h>
#include<string.h>
const int N=30;
int up[N],down[N],dp[N];
int a,n,m,x;
const int M=1e9+10;
int main()
{
scanf("%d%d%d%d",&a,&n,&m,&x);
for(int i=0;i<=M;++i)
{
memset(up,0,sizeof up);
memset(down,0,sizeof down);
memset(dp,0,sizeof dp);
dp[1]=a;up[1]=a;down[1]=0;
dp[2]=a;up[2]=i;down[2]=i;
bool flag=0;
for(int j=3;j<=n;++j)
{
up[j]=up[j-1]+up[j-2];
down[j]=up[j-1];
dp[j]=dp[j-1]+up[j]-down[j];
if(dp[j]<0)
{
flag=1;
break;
}
}
if(flag==1) continue;
if(n==x)
{
printf("0\n");
return 0;
}
if(dp[n-1]==m)
{
printf("%d",dp[x]);
return 0;
}
//printf("dp=%d\n",dp[n-1]);
}
return 0;
}
首先观察时间复杂度,首先,在已知上下车人数的情况下,通过递推计算出第m站的人数时间复杂度极地(数据范围只有20)
所以我们可以考虑假设上车和下车的人数,递推出最后一站的下车人数,如果最后一站的下车人数符合要求,那么就说明假设正确,就可以输出第x站的结果。
但是在计算的过程中有几个问题:
1.首先车上不能没有人,如果车上只有5个人,那么这一站最多只能下5人,不能下更多。但是因为题目中人数是不断上升的,所以这个限制条件其实不存在。
if(dp[j]<0)
{
flag=1;
break;
}
2.第二,假设的上下车人数并不一定是小于等于a的(本来我没有意识到这一点),并且也是可以等于0的。如果等于0,程序也不会错误地结束,但是如果不写等于0,会有一个点答案错误,所以在假设正确的情况下,我们可以适当地扩大暴力搜索的范围。
for(int i=0;i<=M;++i)
当然这题也能使用斐波那契数列来完成,速度相比我这种暴力更快,像我这种垃圾也就只能想出暴力的方法啦!