• 17995 Stupid thief 组合数学


    17995 Stupid thief

    时间限制:1000MS  内存限制:65535K
    提交次数:0 通过次数:0

    题型: 编程题   语言: 不限定

     

    Description

    A stupid thief has just discovered the treasure in a cave. There are N bottles filled with gold coins.
    Because of darkness, he can't see the exact number of coins in each bottle. He only knows the range of the coins’ number in each bottle.
    The lower bound of i-th bottle is low[i] and the upper bound is up[i].
    Now, He decides to take some of the bottles( at least one bottle) . He wants to know how many kinds of possible coins’ number he would take.
    




    输入格式

    The input will contain multiple cases.
    The first line is a integer T, the number of test cases,at most 100 cases.
    Then T cases follow.
    The first line of each case, is an integer N (1<=N<=15), that represents the number of bottles.
    Then N lines follow, each contains two integers low[i] and up[i] (1<=low[i]<=up[i]<=1000000), that represents the i-th bottle’s lower bound and upper bound.
    



    输出格式

    For each test case, print the answer in a single line, which is the number of possible coins’ number he would take.



     

    输入样例

    3
    1
    10 15
    2
    3 5
    4 5
    3
    2 2
    3 5
    4 8
    



     

    输出样例

    6
    7
    14
    



     

    提示

    In the first sample, the possible coin number is 10,11,12,13,14,15;
    In the second sample,the possible coin number is 3,4,5,7,8,9,10;
    In the three sample,the possible coin number is the range [2,15];
    



     

    来源

     Farmer 

    http://acm.scau.edu.cn:8000/uoj/mainMenu.html

    给定N个区间,N <= 15,然后每个区间就是[L, R]这个范围,要求你任取x个区间,相加后得到的数字有多少种不同的结果。

    考虑只选一个区间,那么数字就是[L, R]

    选两个的话,[L[1], R[1]] 和 [L[2], R[2]]能得到的结果就是[L[1] + L[2], R[1] + R[2]]

    因为区间的数字是连续的,所以意思就是选取最小的和最小的相加就是下界,最大的和最大的相加就是上界。

    那么可以暴力枚举所有不同的组合,得到2^n - 1个范围,要对这些范围进行去重即可。

    去重就是

    [1, 2]和[1, 10]的,算作[1, 10]、因为问的只是种类嘛。

    然后首先对L排序,再合并。

    保证L最小后,区间合并的概率最大,也是最优。

    排序R的话,会有bug

    比如排序完后是

    1, 2

    3, 3

    1, 10

    等。

    数据

    3

    1 2

    3 3

    1 10

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    const int maxn = 15 + 2;
    struct node {
        LL L, R;
        bool operator < (const struct node & rhs) const {
            return L < rhs.L;
        }
    }query[1 << maxn], b[maxn];
    int slc[maxn];
    void work() {
        int n;
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) {
            scanf("%lld%lld", &b[i].L, &b[i].R);
        }
        int end = (1 << n) - 1;
        int len;
        int lenq = 0;
        for (int i = 1; i <= end; ++i) {
            len = 0;
            for (int j = 1; j <= n; ++j) {
                if ((1 << (j - 1)) & (i)) {
                    slc[++len] = j;
                }
            }
            LL mi = 0;
            LL mx = 0;
            for (int j = 1; j <= len; ++j) {
                mi += b[slc[j]].L;
                mx += b[slc[j]].R;
                if (mx < 0) while(1);
            }
            ++lenq;
            query[lenq].L = mi;
            query[lenq].R = mx;
        }
        sort(query + 1, query + 1 + lenq);
        query[lenq + 1].L = query[lenq + 1].R = -1;
        lenq++;
        LL ans = 0;
        LL L = query[1].L;
        LL R = query[1].R;
    //    for (int i = 1; i <= lenq; ++i) {
    //        cout << query[i].L << " " << query[i].R << endl;
    //    }
        for (int i = 2; i <= lenq; ++i) {
            if (i == lenq) {
                ans += R - L + 1;
                break;
            }
            if (R >= query[i].L) {
                R = max(R, query[i].R);
            } else {
                ans += R - L + 1;
                R = query[i].R;
                L = query[i].L;
            }
        }
        cout << ans << endl;
    }
    
    int main() {
    #ifdef local
        freopen("data.txt","r",stdin);
    #endif
        int t;
        scanf("%d", &t);
        while (t--) work();
        return 0;
    }
    View Code
  • 相关阅读:
    Python之路(第十七篇)logging模块
    Python之路(第十五篇)sys模块、json模块、pickle模块、shelve模块
    Python之路(第十四篇)os模块
    Python之路(第十三篇)time模块、random模块、string模块、验证码练习
    Python之路(第十二篇)程序解耦、模块介绍导入安装、包
    Python编程笔记(第三篇)【补充】三元运算、文件处理、检测文件编码、递归、斐波那契数列、名称空间、作用域、生成器
    Python之路(第十一篇)装饰器
    Python之路(第十篇)迭代器协议、for循环机制、三元运算、列表解析式、生成器
    Python之路(第九篇)Python文件操作
    Python编程笔记(第二篇)二进制、字符编码、数据类型
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6053199.html
Copyright © 2020-2023  润新知