最近在刷ccf 做到这样一个题很有意思,记录下来
差分方法与记忆化搜索均可,此处使用记忆化搜索
c++ 版 https://blog.csdn.net/imotolove/article/details/82777819
java 具体实现如下
import java.util.Scanner;
public class c20180904 {
static int total;
static int []first;
static int []second;
static boolean [][][]visit;
static void dfs(int n,int x,int y){
if(visit[n][x][y])return;//剪枝,不加只有80分
visit[n][x][y]=true;
if(n==total-1){
if((3*second[n]-x)/2==second[total]||(3*second[n]-x+1)/2==second[total]||(3*second[n]-x+2)/2==second[total]){ //最后一天菜价
for(int i=1;i<=n;++i) //输出
System.out.print(first[i]+" ");
for(int i=0;i<3;++i)
{
if((3*second[n]-x+i)/2==second[total]) //输出最后一天菜价
{
System.out.print(3*second[n]-x-y+i+" ");
System.exit(0);//终止
}
}
}
return;
}
for(int i =0;i<3;i++){
first[n+1]=3*second[n]-x-y+i;
if(first[n+1]>0){
dfs(n+1,y,first[n+1]);
}
}
}
public static void main(String []args){
Scanner sc = new Scanner(System.in);
total = sc.nextInt();
second = new int[400];
first = new int[400];
visit = new boolean[301][301][301];
for(int i =1;i<=total;i++){
second[i] = sc.nextInt();
}
for(int i=1;i<=2*second[1];i++)
{
first[1]=i;
first[2]=2*second[1]-i; //第一天菜价,有两种可能
dfs(2,first[1],first[2]);
first[1]=i;
first[2]=2*second[1]-i+1; //第二种可能
dfs(2,first[1],first[2]);
}
}
}