数据范围小,可以暴力枚举,即dfs枚举或二进制枚举
第一种(二进制枚举)O(n 2^n):
#include <bits/stdc++.h>
using namespace std;
const int N = 20;
int a[N];
int n, l, r, x;
int main()
{
cin >> n >> l >> r >> x;
for (int i = 0; i < n; ++i) cin >> a[i];
int res = 0;
for (int i = 1; i < 1 << n; ++i)//1 ~ 2^n-1 枚举
{
int s = 0, cnt = 0, mi = 1e7, ma = 0;
for (int j = 0; j < n; ++j)
{
if (i >> j & 1) //如果i的第j位为1
{
s += a[j];
mi = min(mi, a[j]);
ma = max(ma, a[j]);
cnt ++;
}
}
if (cnt >= 2 && ma - mi >= x && s >= l && s <= r) res ++;
}
cout << res << endl;
return 0;
}
第二种(dfs暴力枚举):
每一个数都
#include <bits/stdc++.h> using namespace std; const int N = 20; int a[N]; int n, l, r, x; int dfs(int u, int cnt, int s, int mi, int ma) { if (u == n) { if (s >= l && s <= r && ma - mi >= x && cnt >= 2) return 1; else return 0; } int res = 0; res += dfs(u + 1, cnt + 1, s + a[u + 1], min(mi, a[u + 1]), max(ma, a[u + 1])); //选下一层,即a[u + 1] res += dfs(u + 1, cnt, s, mi, ma); //不选下一层 return res; } int main() { cin >> n >> l >> r >> x; for (int i = 1; i <= n; ++i) cin >> a[i]; cout << dfs(0, 0, 0, 1e7, 0) << endl; //初始化 return 0; }
有选与不选两种选择
第三种(dfs加剪枝):
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 20;
int n, l, r, x;
int a[N];
int s;
int dfs(int m, int idx, int s)
{
if (m == n) return 0;//不能a[m - 1] == a[n - 1],有可能4 6 4 6,a[1] == a[3]
int cnt = 0;
for (int i = m; i < n; ++i)
{
s += a[i];
if (s >= l && s <= r && a[i] - a[idx] >= x) cnt ++;
cnt += dfs(i + 1, idx, s);
s -= a[i];
}
return cnt;
}
int main()
{
cin >> n >> l >> r >> x;
for (int i = 0; i < n; ++i) cin >> a[i];
sort(a, a + n);
int ans = 0;
for (int i = 0; i < n - 1; ++i)
{
int r = dfs(i + 1, i, a[i]);
// printf("%d\n", r);
ans += r;
}
printf("%d\n", ans);
return 0;
}