zoukankan      html  css  js  c++  java
  • 51NOD 1821 最优集合 栈

    1821 最优集合
     
    一个集合S的优美值定义为:最大的x,满足对于任意i∈[1,x],都存在一个S的子集S',使得S'中元素之和为i。
    给定n个集合,对于每一次询问,指定一个集合S1和一个集合S2,以及一个数k,要求选择一个S2的子集S3(|S3|<=k),使得S1∪S3的优美值最大。
    (集合元素可以重复)
    Input
    第一行一个数n,(n<=1000)
    接下来n行,每行描述一个集合:
    第一个数m,表示集合大小,接下来m个数,表示集合中的元素(m<=1000,元素<=10^9)
    第n+2行一个数T,表示询问次数(T<=10000)
    接下来T行,每行3个数a,b,k,表示指定第a个集合为S1,第b个集合为S2,k的意义如题(a<=n,b<=n,k<=100,000)
    Output
    T行,每行一个数,表示对应询问所能达到的最大优美值
    Input示例
    2
    6 1 2 3 8 15 32
    6 1 1 1 1 1 1
    1
    1 2 3
    Output示例
    64
     
    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define ls i<<1
    #define rs ls | 1
    #define mid ((ll+rr)>>1)
    #define pii pair<int,int>
    #define MP make_pair
    typedef long long LL;
    const long long INF = 1e18+1LL;
    const double Pi = acos(-1.0);
    const int N = 1e3+10, maxn = 1e3+20, mod = 1e9+7, inf = 2e9;
    
    int a[N][N],n,T,b[N],H[N];
    stack <int > q;
    void solve(int ii,int jj,int k) {
        LL ans = 0;
        int tmp1 = 1;
        while(!q.empty()) q.pop();
        for(int i = 1; i <= a[ii][0]; ) {
            if(ans + 1 >= a[ii][i]) {
                ans += a[ii][i];
                ++i;
            }
            else{
                if(!k) break;
                if(q.empty()) break;
                while(!q.empty() && k) {
                   ans += q.top(),q.pop(),k--;
                   break;
                }
            }
            for(int j = tmp1; j <= a[jj][0]; ++j) {
                if(ans + 1 >= a[jj][j]) {
                    q.push(a[jj][j]);
    
                    tmp1 = j+1;
                }
                else break;
            }
        }
        while(!q.empty() && k) {
            ans += q.top();
            q.pop();
            k--;
        }
        printf("%lld
    ",ans);
    }
    
    int main() {
        scanf("%d",&n);
        for(int i = 1; i <= n; ++i) {
            scanf("%d",&a[i][0]);
            for(int j = 1; j <= a[i][0]; ++j) {
                scanf("%d",&a[i][j]);
            }
            sort(a[i] + 1, a[i] + a[i][0] + 1);
        }
        scanf("%d",&T);
        while(T--) {
            int i,j,k;
            scanf("%d%d%d",&i,&j,&k);
            solve(i,j,k);
        }
        return 0;
    }

        
  • 相关阅读:
    从Oracle提供两种cube产品说开
    Sql Server DWBI的几个学习资料
    Unload Oracle data into text file
    初学Java的几个tips
    我常用的Oracle知识点汇总
    benefits by using svn
    如何在windows上使用putty来显示远端linux的桌面
    building commercial website using Microsoft tech stack
    Understand Thread and Lock
    Update google calendar by sunbird
  • 原文地址:https://www.cnblogs.com/zxhl/p/6627332.html
Copyright © 2011-2022 走看看