思路:
深度搜索算法题,根据前面的商家的菜价和平均值推出之后的商家菜价范围,递归完成遍历。类似于迷宫,走过的路要做好标记(记忆化搜索),避免重复,否则会超时。
第一家商店和最后一家商店要特殊处理一下,因为只有一个邻居。
#include<bits/stdc++.h>
using namespace std;
const int maxn=301;
int price[maxn],n,visit[maxn][maxn][maxn];
vector<int>ans;
void dfs(int x){
int sum;
if(x==1){ //第一家商店特殊处理
sum=price[x]*2;
for(int p=1;p<=sum;p++){
ans.push_back(p);
ans.push_back(sum-p);
dfs(2);
ans[2]++;
dfs(2);
ans.pop_back();
ans.pop_back();
}
return;
}
//剪枝
if(visit[x][ans[x-1]][ans[x]]==1)return;//访问标记
visit[x][ans[x-1]][ans[x]]=1;
sum=price[x]*3;
if(x==n){ //最后一家商店特殊处理
if((ans[n]+ans[n-1])/2==price[n]){
int tag=0;
for(auto it:ans){
if(tag++)cout<<it<<' ';
}
exit(0);//结束进程
}
return;
}
//中间分支
for(int i=0;i<3;i++){
int next=sum-ans[x]-ans[x-1]+i;
if(next>=1){
ans.push_back(next);
dfs(x+1);
ans.pop_back();
}
}
return;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>price[i];
}
ans.push_back(-1);//加入任意一个元素,让序号对应商家编号
dfs(1);
return 0;
}
样例:
/*
8
2 2 1 3 4 9 10 13
*/