CodeForces 6D Lizards and Basements 2 (dfs)

题意:给出一串n个元素序列、a和b,只能选择编号2 ~ n-1的s数字减a,并将相邻两数字减b,要使得所有元素为负,问至少需要多少次选择,选择是怎样的。

题解:dfs
我们可以发现只有2 ~ n-1编号的数字能够被选择,那么就以 前一个元素为负 为标准,进行dfs,终点是三个元素都为负。

注意递归的时候,若当前选择次数已经超过了存储的答案,那就进行剪枝。

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<fstream>
#include<set>
#include<map>
#include<sstream>
#include<iomanip>
#define ll long long
using namespace std;
int n, a, b, h[11], num, t[11];
vector<int> v;
void dfs(int idx, int nn) {
	if (nn >= num) return;
	if (idx == n) {
		if (h[idx] < 0) {
			num = nn;
			v.clear();
			for (int i = 2; i <= n - 1; i++) {
				v.push_back(t[i]);
			}
		}
		return;
	}
	int temp = max(h[idx - 1] / b + 1, max(h[idx] / a + 1, h[idx + 1] / b + 1));
	for (int i = 0; i <= temp; i++) {
		if (h[idx - 1] >= i * b) continue;
		h[idx - 1] -= i * b;
		h[idx + 1] -= i * b;
		h[idx] -= i * a;
		t[idx] += i;
		dfs(idx + 1, nn + i);
		h[idx - 1] += i * b;
		h[idx + 1] += i * b;
		h[idx] += i * a;
		t[idx] -= i;
	}
}
int main() {
	num = 0x3f3f3f3f;
	scanf("%d%d%d", &n, &a, &b);
	for (int i = 1; i <= n; i++) scanf("%d", &h[i]);
	dfs(2, 0);
	printf("%d\n", num);
	for (int i = 0; i <= n - 3; i++) {
		for (int j = 1; j <= v[i]; j++) {
			printf("%d ", i + 2);
		}
	}
	return 0;
}
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 像素格子 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读