题意:给出一串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;
}