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 }

 

posted @ 2017-02-26 21:28  _yxg123  阅读(117)  评论(0编辑  收藏  举报