zoukankan      html  css  js  c++  java
  • [BZOJ] 1046 [HAOI2007]上升序列

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2544  Solved: 1466
    [Submit][Status][Discuss]
    Description
    windy有 N 条木板需要被粉刷。 每条木板被分为 M 个格子。 每个格子要被刷成红色或蓝色。 windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色。 每个格子最多只能被粉刷一次。 如果windy只能粉刷 T 次,他最多能正确粉刷多少格子? 一个格子如果未被粉刷或者被粉刷错颜色,就算错误粉刷。
    
    Input
    输入文件paint.in第一行包含三个整数,N M T。 接下来有N行,每行一个长度为M的字符串,'0'表示红色,'1'表示蓝色。
    
    Output
    输出文件paint.out包含一个整数,最多能正确粉刷的格子数。
    
    Sample Input
    3 6 3
    
    111111
    
    000000
    
    001100
    
    Sample Output
    16
    
    HINT
    30%的数据,满足 1 <= N,M <= 100 <= T <= 100100%的数据,满足 1 <= N,M <= 500 <= T <= 2500

    倒着求LIS,怎么求呢?把树状数组下标”取反”,更新倒着更新,a[i]-1改成a[i]+1。
    贪心统计答案,注意是下标最小。

    血的教训 离散化没有-1

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    
    inline int rd(){
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    const int MAXN=1000005;
    
    int n,m,tot;
    int a[MAXN],b[MAXN],f[MAXN];
    int val[MAXN];
    
    int t[MAXN];
    void updata(int x,int w){
        for(int i=tot+1-x;i<=n;i+=i&-i) t[i]=max(t[i],w);
    }
    int query(int x){
        int ret=-1;
        for(int i=tot+1-x;i;i-=i&-i) ret=ret>t[i]?ret:t[i];
        return ret;
    }
    
    int mx;
    int sv[MAXN];
    
    int main(){
    //  freopen("1.in","r",stdin);
    //  freopen("my.out","w",stdout);
        n=rd();
        for(int i=1;i<=n;i++) sv[i]=b[i]=a[i]=rd();
        sort(b+1,b+1+n);
        tot=unique(b+1,b+1+n)-b-1;
        for(int i=1;i<=n;i++){
            //int sav=a[i];
            a[i]=lower_bound(b+1,b+1+tot,a[i])-b-1;//
            //val[a[i]]=sav;
        }
        for(int i=n;i>=1;i--){
            f[i]=query(a[i]+1)+1;
            updata(a[i],f[i]);
            //que[f[i]]=min(que[f[i]],val[a[i]]);
            mx=mx<f[i]?f[i]:mx;
        }
        m=rd();
        int x;
        for(int i=1;i<=m;i++){
            x=rd();
            if(x>mx) {puts("Impossible");continue;}
            int tmp=0;
            for(int j=1;j<=n;j++){
                if(f[j]>=x&&sv[j]>tmp) {//=
                    tmp=sv[j];x--;
                    cout<<tmp<<" ";
                    if(x==0) {printf("
    ");break;}
                }
            }
        }
    
        return 0;
    }
    

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9247394.html

  • 相关阅读:
    HDU 2544 最短路
    Codeforces Round #358 (Div. 2) Alyona and Strings
    Codeforces Round #358 (Div. 2) Alyona and the Tree
    Codeforces Round #357 (Div. 2) Runaway to a Shadow
    pycharm快捷键和一些常用的设置
    Python不同功能的函数
    面向对象技术简介
    数据结构
    python学习笔记
    ORACLE基本语法
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9247394.html
Copyright © 2011-2022 走看看