Codeforces Round #306 (Div. 2) B. Preparing Olympiad dfs
题目链接:
http://codeforces.com/contest/550/problem/B
题意:
有n门课,然后让你选择一些课,要求这些课程的和小于等于r,大于等于l,最大值减去最小值至少为x
然后问你有多少种分法
题解:
数据范围小 n<=15 所以可以把n门课 变成二进制的状态
也可以直接dfs
代码:
dfs ~
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 #define MS(a) memset(a,0,sizeof(a)) 5 #define MP make_pair 6 #define PB push_back 7 const int INF = 0x3f3f3f3f; 8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL; 9 inline ll read(){ 10 ll x=0,f=1;char ch=getchar(); 11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 12 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 13 return x*f; 14 } 15 ////////////////////////////////////////////////////////////////////////// 16 const int maxn = 1e5+10; 17 18 int n,vis[20]; 19 ll le,ri,x,a[20]; 20 int ans; 21 22 void dfs(int t, ll sum, ll mi,ll mx){ 23 if(sum > ri) return ; 24 25 if((mx-mi)>=x && (sum>=le) && (sum<=ri)) 26 ans++; 27 for(int i=t; i<=n; i++){ 28 if(!vis[i]){ 29 vis[i] = 1; 30 dfs(i,sum+a[i],min(a[i],mi),max(a[i],mx)); 31 vis[i] = 0; 32 } 33 } 34 } 35 36 int main(){ 37 n = read(),le=read(),ri=read(),x=read(); 38 for(int i=1; i<=n; i++) 39 a[i] = read(); 40 41 dfs(1,0,INF,-1); 42 43 cout << ans << endl; 44 45 return 0; 46 } 47 每位表示状态 选和不选 48 49 #include <bits/stdc++.h> 50 using namespace std; 51 typedef long long ll; 52 #define MS(a) memset(a,0,sizeof(a)) 53 #define MP make_pair 54 #define PB push_back 55 const int INF = 0x3f3f3f3f; 56 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL; 57 inline ll read(){ 58 ll x=0,f=1;char ch=getchar(); 59 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 60 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 61 return x*f; 62 } 63 ////////////////////////////////////////////////////////////////////////// 64 const int maxn = 1e5+10; 65 66 ll n,le,ri,x,a[20]; 67 int ans; 68 69 int main(){ 70 n = read(),le=read(),ri=read(),x=read(); 71 for(int i=0; i<n; i++) 72 a[i] = read(); 73 74 for(int i=0; i<(1<<n); i++){ 75 ll cnt=0,sum=0,mi=INFLL,mx=-1; 76 for(int j=0; j<n; j++){ 77 if(i&(1<<j)){ 78 cnt++; 79 sum += a[j]; 80 mi = min(mi,a[j]); 81 mx = max(mx,a[j]); 82 } 83 } 84 if(cnt>=2 && (mx-mi)>=x && sum>=le && sum<=ri) 85 ans++; 86 } 87 88 cout << ans << endl; 89 90 return 0; 91 }