问题描述
A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树。园林部门到指令后,初步规划出n个种树的位置,顺时针编号1到n。并且每个位置都有一个美观度Ai,如果在这里种树就可以得到这Ai的> 美观度。但由于A城市土壤肥力欠佳,两棵树决不能种在相邻的位置(i号位置和i+1号位置叫相邻位置。值得注意的是1号和n号也> 算相邻位置!)。最终市政府给园林部门提供了m棵树苗并要求全部种上,请你帮忙设计种树方案使得美观度总和最大。如果无法> > 将m棵树苗全部种上,给出无解信息。
输入格式
输入的第一行包含两个正整数n、m。
第二行n个整数Ai。
输出格式
输出一个整数,表示最佳植树方案可以得到的美观度。如果无解输出“Error!”,不包含引号。
样例输入
7 3
1 2 3 4 5 6 7
样例输出
15
样例输入
7 4
1 2 3 4 5 6 7
样例输出
Error!
数据规模和约定
对于全部数据,满足1<=m<=n<=30;
其中90%的数据满足m<=n<=20
-1000<=Ai<=1000
package test;
import java.util.*;
public class Main {
static int hole, tree; //洞,树
static int[] beauty; //美观度
static boolean[] if_userd; //洞是否被用
static int max;
// static boolean flag = false;
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
hole = sc.nextInt();
tree = sc.nextInt();
beauty = new int[hole];
if_userd = new boolean[hole];
for(int i=0;i<hole;i++)
beauty[i] = sc.nextInt();
if(hole>=2*tree) //只有当洞的数量大于树数量的两倍时才满足题意
{
doit(tree,0,0);
System.out.println(max);
}
else
System.out.println("Error!");
// doit(tree,0,0);
// if(flag) System.out.println(max);
// else System.out.println("Error!");
}
private static void doit(int remain_tree, int hole_num, int sum){ //remain_tree 剩余的树,hole_num 第几个洞, sum 总的美观度
//当剩余树的数量为0时完成递归
if(remain_tree==0){
if(sum>max)
max = sum;
// flag = true;
return;
}
for(int i = hole_num;i<hole;i++){ //从hole_num 的洞往后种
//第i个洞没有被用时
if(if_userd[i] == false){
if(i<hole-1) //不是最后一个洞时
if_userd[i+1] = true; //在第i个洞种树则i+1个洞不能使用
if(i==0) { //种在第0个洞时,最后一个洞不能种
if_userd[i] = true;
// if_userd[hole - 1] = true;
}
doit(remain_tree-1,i+1,sum+beauty[i]); //第i个洞种下,然后种后面的洞,树的数量减1
//回溯
if(i<hole-1)
if_userd[i+1] = false;
if(if_userd[0] == true)
if_userd[hole-1] = true;
if(i ==0 ) {
if_userd[i] = false;
if_userd[hole - 1] = false;
}
}
}
}
}