ccf再卖菜

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/imotolove/article/details/82777819

这题一看就是暴搜,想都不想就写了个暴搜程序(不考虑复杂度),但这题正解应该是记忆化搜索。。

已知a[n],求b[n],其中a[n]是所给数据,b[n]是要求的菜价

其中有 (b[n-1]+b[n]+b[n+1])/3=a[n](n表示第n天菜价)

所以b[n+1]=3*a[n]-b[n-1]-b[n],或b[n+1]=3*a[n]-b[n-1]-b[n]+1,或b[n+1]=3*a[n]-b[n-1]-b[n]+2

有三种结果是因为3的余数可以是0,1,2

递推关系式就求出来了,每次用b[n-1],b[n],得出b[n+1],所以用dfs暴搜

这里要考虑特殊情况,就是第一天和最后一天是除以2,所以写两种情况就可以了

其他情况看代码注释吧,。

#include<iostream>
#include<cstdlib>
using namespace std;
int t,count;
int a[400],b[400];//输入菜价,所求菜价 
bool f[301][301][301]; //储存状态信息,也就是dfs的n,x,y 
void dfs(int n,int x,int y)//分别是搜到第n天,b[n-1](求到了第n-1天的菜价),b[n](求到了第n天的菜价)
{ 
	if(f[n][x][y])return;//剪枝,不加只有80分 
	f[n][x][y]=1;
	if(n==t-1) //最后一天菜价特殊处理,所以n只用等于t-1就够了 
	{
		if((3*a[n]-x)/2==a[t]||(3*a[n]-x+1)/2==a[t]||(3*a[n]-x+2)/2==a[t]) //最后一天菜价 
		{
			//cout<<count<<endl;
			for(int i=1;i<=n;++i)    //输出 
			cout<<b[i]<<" ";
			for(int i=0;i<3;++i)
			{
				if((3*a[n]-x+i)/2==a[t]) //输出最后一天菜价
				{
					cout<<3*a[n]-x-y+i;
					exit(0);  //直接结束程序,这样用时更短 
				}
			}
		}
		return;
	}
	for(int i=0;i<3;++i) 
	{
		b[n+1]=3*a[n]-x-y+i; //递推关系式 
		if(b[n+1]>=1)
		dfs(n+1,y,b[n+1]);
	}
}
int main()
{
	cin>>t;
	for(int i=1;i<=t;++i)
	cin>>a[i];
	for(int i=1;i<=2*a[1];++i)
	{
		b[1]=i,b[2]=2*a[1]-i;  //第一天菜价,有两种可能 
		dfs(2,i,b[2]);
		b[1]=i,b[2]=2*a[1]-i+1; //第二种可能 
		dfs(2,i,b[2]);
	} 
	return 0;
}
/*
290
8 8 7 11 12 11 22 23 23 8 8 5 5 5 5 5 5 5 6 7 7 7 6 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
5 6 7 8 8 7 5 5 5 8 25 31 31 15 8 28 28 48 25 25 5 6 7 8 8 7 5 5 5 5 5 5 5 5 5 5 5 5 5 
5 5 6 7 8 8 6 5 5 5 5 5 5 5 21 21 21 5 5 5 5 5 27 28 29 7 6 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 7 8 8 7 5 5 5 5 5 
5 5 5 5 5 5 5 5 5 5 6 7 8 8 7 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 8 8 7 11 12 11 22 23 23 8
8 8 7 11 12 11 22 23 23 8 8 8 7 11 12 11 22 23 23 8 8 8 7 11 12 11 22 23 23 8
8 8 7 11 12 11 22 23 23 8 8 8 7 11 12 11 22 23 23 8 8 8 7 11 12 11 22 23 23 8
8 8 7 11 12 11 22 23 23 8 8 8 7 11 12 11 22 23 23 8 8 8 7 11 12 11 22 23 23 8
8 8 7 11 12 11 22 23 23 8 8 8 7 11 12 11 22 23 23 8 8 8 7 11 12 11 22 23 23 8
*/

运行次数为199452次,这样的程序结果只有30分

当加入记录状态数组f[x][y][z]后,运行次数只有1462次,运行时间大大缩短,目前ccf没放题,还不知道记搜多少分,,,

但粗略的考虑,暴搜时间复杂度为3^n,记搜时间复杂度为n*300*300,应该不会超时。

来年再战!

刚刚把程序提交了,100分,。

猜你喜欢

转载自blog.csdn.net/imotolove/article/details/82777819