ccf csp-201809-4-再卖菜(dfs+剪枝)

原试题点击此处

思路:

d1存放第一天菜价,d2存放第二天菜价.

  • 递归体————其中有 (d1[n-1] + d1[n] + d1[n+1]) /3 = d2[n]
    所以d1[n+1] = 3 * d2[n] - d1[n-1] - d1[n],…… ……①
    或d1[n+1] = 3 * d2[n] - d1[n-1] - d1[n] + 1,…… ……②
    或d1[n+1] = 3 * d2[n] - d1[n-1] - d1[n] + 2 …… ……③
    ①②③即为递推表达式,令d[n-1]=x ,d[n]=y, n=n,作为传入递归函数的参数,递归求解d1[n+1]
  • 递归出口————直到遇到倒数第二家商铺:
    (x + y +d1[t-1]) / 3 = d2[t-1] …… ……④
    (y + d1[t-1]) / 2 = d2[t] …… ……⑤
    抓住y +d1[t-1]这个共同的整体,问题就迎刃而解了。

代码如下

#include<iostream>

using namespace std;
int d1[400],d2[400];int t;
int visit[400][400][400];
void dfs(int n,int x,int y){
	if(visit[n][x][y]) return;
	visit[n][x][y] = 1;
	if(n == t-1){
		if((3*d2[t-1]-x)/2==d2[t]||(3*d2[t-1]-x+1)/2==d2[t]||(3*d2[t-1]-x+2)/2==d2[t]){
			for(int i = 1; i <= n; i++){
				cout<<d1[i]<<" ";
			}
			for(int i = 0; i < 3; i++){
				if((3*d2[t-1]-x+i)/2==d2[t]){
					cout<<3*d2[t-1]-x+i-y<<endl;
					exit(0);
				}
			}
		}
		//return;
	}
	for(int i = 0; i < 3; i++){
		d1[n+1]=3*d2[n]-x-y+i;
		if(d1[n+1]>=1) dfs(n+1,y,d1[n+1]);
	}
}
int main()
{
	scanf("%d", &t);
	for(int i = 1; i <= t; i++){
		scanf("%d", &d2[i]);
	}
	for(int i = 1; i <= 2*d2[1]; i++){
		d1[1]=i,d1[2]=2*d2[1]-i;
		dfs(2,d1[1],d1[2]);
		d1[1]=i,d1[2]=2*d2[1]-i+1;
		dfs(2,d1[1],d1[2]);
	}
	return 0;
}
发布了118 篇原创文章 · 获赞 755 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_42437577/article/details/104351777