Codeforces Round #306 (Div. 2), problem: (B) Preparing Olympiad【dfs或01枚举】
题意: 给出n个数字,要求在这n个数中选出至少两个数字,使得它们的和在l,r之间,并且最大的与最小的差值要不小于x。n<=15
二进制
利用二进制, 第i位为1则加上a[i], 为0则不加,
#include<iostream> #include <algorithm> #include <cmath> #include<map> using namespace std; typedef long long LL; int a[20]; int main() { int n,l,r,x, res=0; cin >> n >> l >> r >>x; for(int i = 0; i < n; i ++)cin >> a[i]; for(int i =1; i < (1<<n); i ++) { int idx = 0, sum = 0; int minn = 999999999, maxx = 0; for(int j = i; j; j >>=1, idx ++) if(j&1==1) { sum += a[idx]; maxx = max(maxx,a[idx]); minn = min(minn, a[idx]); } if(maxx -minn >= x && sum <= r && sum >= l) res ++; } cout << res <<'\n'; return 0; }
dfs方法
#include<iostream> #include <algorithm> #include <cmath> #include<map> using namespace std; typedef long long LL; int a[20]; int n,l,r,x, res=0; void dfs(int sum, int maxx, int minn, int num) { if(maxx - minn >= x && sum >= l && sum <= r && num==n) res ++; if(num==n)return; dfs(sum + a[num], max(maxx, a[num]), min(minn, a[num]), num +1); dfs(sum, maxx, minn, num+1); } int main() { cin >> n >> l >> r >>x; for(int i = 0; i < n; i ++)cin >> a[i]; dfs(0,0,999999999,0); cout << res <<'\n'; return 0; }