codeforces B - Preparing Olympiad(dfs或者状态压缩枚举)

                                B. Preparing Olympiad

You have n problems. You have estimated the difficulty of the i-th one as integer ci. Now you want to prepare a problemset for a contest, using some of the problems you‘ve made.

A problemset for the contest must consist of at least two problems. You think that the total difficulty of the problems of the contest must be at least l and at most r. Also, you think that the difference between difficulties of the easiest and the hardest of the chosen problems must be at least x.

Find the number of ways to choose a problemset for the contest.

Input

The first line contains four integers nlrx (1 ≤ n ≤ 15, 1 ≤ l ≤ r ≤ 109, 1 ≤ x ≤ 106) — the number of problems you have, the minimum and maximum value of total difficulty of the problemset and the minimum difference in difficulty between the hardest problem in the pack and the easiest one, respectively.

The second line contains n integers c1, c2, ..., cn (1 ≤ ci ≤ 106) — the difficulty of each problem.

Output

Print the number of ways to choose a suitable problemset for the contest.

Sample test(s)

input

3 5 6 11 2 3

output

2

input

4 40 50 1010 20 30 25

output

2

input

5 25 35 1010 10 20 10 20

output

6

Note

In the first example two sets are suitable, one consisting of the second and third problem, another one consisting of all three problems.

In the second example, two sets of problems are suitable — the set of problems with difficulties 10 and 30 as well as the set of problems with difficulties 20 and 30.

In the third example any set consisting of one problem of difficulty 10 and one problem of difficulty 20 is suitable.

题目信息:从n个数种选择至少两个数,这些数的和在l和r之间,并且这些数的最大值-最小值要大于等于x

    思路:由于n个数值很少,那么就采用暴力枚举。关与枚举采用了下面的两种方法:dfs 或者 直接状态压缩枚举所有的状况

#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<algorithm>
#define N 100005
using namespace std;
int a[20];
int n, l, r, x;
int cnt;
int ans;
void dfs(int i, int cc, int sum, int minn, int maxn){
    if(cc == cnt){
        if(sum>=l && sum<=r && maxn - minn>=x)
            ++ans;
        return;
    }
    if(i>=n) return;
    dfs(i+1, cc+1, sum+a[i], min(minn, a[i]), max(maxn, a[i]));
    dfs(i+1, cc, sum, minn, maxn);
}

int main(){
    cin>>n>>l>>r>>x;
    for(int i=0; i<n; ++i)
        cin>>a[i];
    for(int i=2; i<=n; ++i){
        cnt = i;
        dfs(0, 0, 0, 10000000, -1);
    }
    cout<<ans<<endl;
    return 0;
} 
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<algorithm>
#define N 100005
using namespace std;
int a[20];
int n, l, r, x;

int main(){
    cin>>n>>l>>r>>x;
    for(int i=0; i<n; ++i)
        cin>>a[i];
    int s = 1<<n;
    int cnt = 0;
    for(int i=1; i<s; ++i){
        int sum = 0, minn = 10000000, maxn = -1;
        for(int j=0; j<n; ++j)
            if((1<<j)&i){
                sum += a[j];
                minn = min(minn, a[j]);
                maxn = max(maxn, a[j]);
            }
        if(sum>=l && sum<=r && maxn-minn>=x)
            ++cnt;
    }
    cout<<cnt<<endl;
    return 0;
} 
时间: 2024-12-24 09:32:37

codeforces B - Preparing Olympiad(dfs或者状态压缩枚举)的相关文章

CodeForces 550B Preparing Olympiad(DFS回溯)

[题目链接]:click here~~ [题目大意] 一组题目的数目(n<=15),每个题目有相应的难度,问你选择一定的题目(大于r个且小于l个)且选择后的题目里最小难度与最大难度差不小于x,求选择方案数. [解题思路]: DFS+回溯. 先发一发比较拙的代码: #include <bits/stdc++.h> using namespace std; const int N=1e5+10; int num[N],mum[N]; int n,m,q,t,l,r; int top,ans,

CodeForces 550B Preparing Olympiad(DFS回溯+暴力枚举)

[题目链接]:click here~~ [题目大意] 一组题目的数目(n<=15),每一个题目有对应的难度,问你选择一定的题目(大于r个且小于l个)且选择后的题目里最小难度与最大难度差不小于x,求选择方案数. [解题思路]: DFS+回溯. 先发一发比較拙的代码: #include <bits/stdc++.h> using namespace std; const int N=1e5+10; int num[N],mum[N]; int n,m,q,t,l,r; int top,ans

codeforces 425B Sereja and Table(状态压缩,也可以数组模拟)

题目 给出一个n*m的01矩阵, 让你最多改变k个里面的值(0变1,1变0), 使得0.1的连通分量是矩阵.输出最少步数 1 ≤ n, m ≤ 100; 1 ≤ k ≤ 10 题解: 如果01连通分量是矩形, 那么矩形一定是这样的: 0101010 1010101 0101010 1010101 (上面的01代表子矩阵块). 也就是每一行要么是相同,要么是相反的. 如果n>k, 肯定有一行是不能改变的,那么枚举这一行,然后其余的要么变相同,要么变相反,看最少的步数. 如果n<k ,那么可以枚举

zoj2977Strange Billboard (状态压缩+枚举)

Strange Billboard Time Limit: 2 Seconds Memory Limit: 65536 KB The marketing and public-relations department of the Czech Technical University has designed a new reconfigurable mechanical Flip-Flop Bill-Board (FFBB). The billboard is a regular two-di

状态压缩+枚举 POJ 3279 Fliptile

题目传送门 1 /* 2 题意:问最少翻转几次使得棋子都变白,输出翻转的位置 3 状态压缩+枚举:和之前UVA_11464差不多,枚举第一行,可以从上一行的状态知道当前是否必须翻转 4 */ 5 #include <cstdio> 6 #include <cstring> 7 #include <algorithm> 8 using namespace std; 9 10 const int MAXN = 20; 11 const int INF = 0x3f3f3f3

UVA 811 The Fortified Forest (凸包 + 状态压缩枚举)

题目链接:UVA 811 Description Once upon a time, in a faraway land, there lived a king. This king owned a small collection of rare and valuable trees, which had been gathered by his ancestors on their travels. To protect his trees from thieves, the king or

uva 818(dfs+图+状态压缩)

题意:有n个环,编号从1到n,给出了一些环环相扣的情况,比如给a和b表示a和b两个环的扣在一起的,每个环都是可以打开的,问最少打开多少个环,然后再扣好,可以让所有的环成为一条链. 题解:状态压缩把所有的打开环的情况枚举出来,然后拿去判断是否成立,更新打开环后的图g[i][j],和每个点的度数,不成立有三种情况,1.计算没有打开的环的度数,如果大于2说明不会有链,2.把没有打开环拿去dfs,访问过就vis[i]++,如果vis[i]>=2说明存在环,3.如果打开的环数num + 1小于链的数量,说

HDU 5339 Untitled (状态压缩枚举)

Untitled Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 570    Accepted Submission(s): 291 Problem Description There is an integer a and n integers b1,-,bn. After selecting some numbers from b

HDU 6607 Time To Get Up(状态压缩+枚举)

题目网址: http://acm.hdu.edu.cn/showproblem.php?pid=6077 思路: 先预处理一下,将每个数字块的"X"看作1,"."看作0,进行状态压缩转换成二进制数,用数组保存.再遍历每个块点的元素,枚举0-9看是否符合当前位数. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 typedef long long l