D. Lizards and Basements 2 (DFS+最优性剪枝)

点击打开链接

http://codeforces.com/contest/6/problem/D

D. Lizards and Basements 2

This is simplified version of the problem used on the original contest. The original problem seems to have too difiicult solution. The constraints for input data have been reduced.

Polycarp likes to play computer role-playing game «Lizards and Basements». At the moment he is playing it as a magician. At one of the last levels he has to fight the line of archers. The only spell with which he can damage them is a fire ball. If Polycarp hits the i-th archer with his fire ball (they are numbered from left to right), the archer loses a health points. At the same time the spell damages the archers adjacent to the i-th (if any) — they lose b (1 ≤ b < a ≤ 10) health points each.

As the extreme archers (i.e. archers numbered 1 and n) are very far, the fire ball cannot reach them. Polycarp can hit any other archer with his fire ball.

The amount of health points for each archer is known. An archer will be killed when this amount is less than 0. What is the minimum amount of spells Polycarp can use to kill all the enemies?

Polycarp can throw his fire ball into an archer if the latter is already killed.

Input

The first line of the input contains three integers n, a, b (3 ≤ n ≤ 101 ≤ b < a ≤ 10). The second line contains a sequence of n integers —h1, h2, ..., hn (1 ≤ hi ≤ 15), where hi is the amount of health points the i-th archer has.

Output

In the first line print t — the required minimum amount of fire balls.

In the second line print t numbers — indexes of the archers that Polycarp should hit to kill all the archers in t shots. All these numbers should be between 2 and n - 1. Separate numbers with spaces. If there are several solutions, output any of them. Print numbers in any order.

Examples
input
3 2 1
2 2 2
output
3
2 2 2 
input
4 3 1
1 4 1 1
output
4
2 2 3 3 

题意:你是火系法师,对面有一排敌人,每个敌人都有HP,你要向他们扔火球,火球对目标 i 有一个主伤害a,对i+1和i -1有一个溅射伤害b。法师只能攻击到2号到n-1号。问你至少要扔多少个火球才能杀死所有敌人,并依次输出每个火球的攻击目标。

题解:DFS暴搜+最优性剪枝。

从2号敌人到n-1号敌人进行搜索,攻击次数从至少杀死第 i - 1个敌人枚举到杀死i-1,i,i+1三个敌人。即h[x-1]<b*i。

DFS(x,times) ,x为目前攻击对象,times为总的攻击次数。


AC代码:

#include<bits/stdc++.h>
using namespace std;
int ans=9999999;
int h[100];
int a,b,n;
vector<int>V;
vector<int>V2;
void dfs(int x,int times)
{
	if(times>=ans)return;//最优性剪枝 
	if(x==n)//只能杀死 第 2 ~ n-1个人 
	{
		if(h[x]<0){
			V2=V;
			ans=times;
		}
		return ;
	}
	for(int i=0; i <= max( h[x-1]/b+1,max( h[x]/a+1, h[x+1]/b+1) );i++)//枚举次数 
	{
		if(h[x-1]<b*i)
		{
			h[x-1] -= b*i;
			h[x] -= a*i;
			h[x+1] -= b*i;
			for(int j=0;j<i;j++) V.push_back(x);
			dfs(x+1,times+i);
			for(int j=0;j<i;j++) V.pop_back();
			h[x-1] += b*i;
			h[x] += a*i;
			h[x+1] += b*i; 
		}
	}
}
int main()
{
	cin>>n>>a>>b;
	for(int i=1;i<=n;i++)cin>>h[i];
	dfs(2,0);
	cout<<ans<<endl;
	for(int i=0;i<V2.size();i++)cout<<V2[i]<<" ";
	cout<<endl;
	return 0;
}


$(function(){ $.fn.extend({ SimpleTree:function(options){ //初始化参数 var option = $.extend({ click:function(a){ } },options); option.tree=this; /* 在参数对象中添加对当前菜单树的引用,以便在对象中使用该菜单树 */ option._init=function(){ /* * 初始化菜单展开状态,以及分叉节点的样式 */ this.tree.find("ul ul").hide(); /* 隐藏所有子级菜单 */ this.tree.find("ul ul").prev("li").removeClass("open"); /* 移除所有子级菜单父节点的 open 样式 */ this.tree.find("ul ul[show='true']").show(); /* 显示 show 属性为 true 的子级菜单 */ this.tree.find("ul ul[show='true']").prev("li").addClass("open"); /* 添加 show 属性为 true 的子级菜单父节点的 open 样式 */ }/* option._init() End */ /* 设置所有超链接不响应单击事件 */ this.find("a").click(function(){ $(this).parent("li").click(); return false; }); /* 菜单项 接受单击 */ this.find("li").click(function(){ /* * 当单击菜单项 * 1.触发用户自定义的单击事件,将该 标签中的第一个超链接做为参数传递过去 * 2.修改当前菜单项所属的子菜单的显示状态(如果等于 true 将其设置为 false,否则将其设置为 true) * 3.重新初始化菜单 */ option.click($(this).find("a")[0]); /* 触发单击 */ /* * 如果当前节点下面包含子菜单,并且其 show 属性的值为 true,则修改其 show 属性为 false * 否则修改其 show 属性为 true */ /* if($(this).next("ul").attr("show")=="true"){ $(this).next("ul").attr("show","false"); }else{ $(this).next("ul").attr("show","true"); }*/ /* 初始化菜单 */ option._init(); }); /* 设置所有父节点样式 */ this.find("ul").prev("li").addClass("folder"); /* 设置节点“是否包含子节点”属性 */ this.find("li").find("a").attr("hasChild",false); this.find("ul").prev("li").find("a").attr("hasChild",true); /* 初始化菜单 */ option._init(); }/* SimpleTree Function End */ }); });
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值