zoukankan      html  css  js  c++  java
  • 杂题训练之八

    https://www.luogu.org/problem/P2215

    初看题目,不就是个最长上升子序列吗?

    但我们知道nlogn的最长上升子序列中定义状态f[i]表示以i结尾的...

    这个题要求以i开头

    所以倒着做最长下降子序列就好了,f只记录长度(解题关键,逆向思考)

    但我发现我一直wa

    wa的代码:

    #include<bits/stdc++.h>
    #define ll long long
    #define il inline
    #define ri register int
    #define lowbit(x) x&(-x)
    using namespace std;
    const int maxn=10005; 
    int n,m,maxx;
    int dp[maxn],C[maxn],a[maxn],t[maxn],xx[maxn];
    il void add(int x,int p){while(x)C[x]=max(C[x],p),x-=lowbit(x);return;}
    il int query(int x){int res=0;while(x<=n)res=max(res,C[x]),x+=lowbit(x);return res;}
    int main(){
    	scanf("%d",&n);
    	for(ri i=1;i<=n;i++)scanf("%d",&a[i]),t[i]=xx[i]=a[i];
    	sort(t+1,t+1+n);int sz=unique(t+1,t+1+n)-t-1;
    	for(ri i=1;i<=n;i++)a[i]=lower_bound(t+1,t+1+n,a[i])-t;
    	for(ri i=n;i>=1;i--){
    	dp[i]=query(a[i]+1)+1;
    	add(a[i],dp[i]);
    	maxx=max(maxx,dp[i]);
    	}
        scanf("%d",&m);
        while(m--){int x;scanf("%d",&x);
        if(x>maxx){printf("Impossible
    ");continue;}
        for(ri i=1;i<=n;i++){
        	if(!x){cout<<endl;break;} 
        	if(dp[i]==x)printf("%d ",xx[i]),x--;
    	}
    	}
    	return 0;
    }
    
    

    为什么呢?因为我太弱了。

    输出的时候根本无法满足它是最长上升的,我只转移了长度

    AC CODE

    #include<bits/stdc++.h>
    #define ll long long
    #define il inline
    #define ri register int
    #define lowbit(x) x&(-x)
    using namespace std;
    const int maxn=10005; 
    int n,m,maxx;
    int dp[maxn],C[maxn],a[maxn],t[maxn],xx[maxn];
    il void add(int x,int p){while(x)C[x]=max(C[x],p),x-=lowbit(x);return;}
    il int query(int x){int res=0;while(x<=n)res=max(res,C[x]),x+=lowbit(x);return res;}
    int main(){
    	scanf("%d",&n);
    	for(ri i=1;i<=n;i++)scanf("%d",&a[i]),t[i]=xx[i]=a[i];
    	sort(t+1,t+1+n);int sz=unique(t+1,t+1+n)-t-1;
    	for(ri i=1;i<=n;i++)a[i]=lower_bound(t+1,t+1+n,a[i])-t;
    	for(ri i=n;i>=1;i--){
    	dp[i]=query(a[i]+1)+1;
    	add(a[i],dp[i]);
    	maxx=max(maxx,dp[i]);
    	}
        scanf("%d",&m);
        while(m--){int x;scanf("%d",&x);
        if(x>maxx){printf("Impossible
    ");continue;}
        int last=0;
        for(ri i=1;i<=n;i++)
        	if(dp[i]>=x&&xx[i]>last){
        	printf("%d ",xx[i]),x--,last=xx[i];
    		if(!x)break;	
    		} puts("");
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    Linux IPC udp/ip socket 编程
    Linux IPC tcp/ip socket 编程
    Linux IPC BSD socket编程基础
    Linux IPC POSIX 信号量
    Linux IPC POSIX 消息队列
    Linux IPC POSIX 共享内存
    Linux IPC System V 信号量
    Linux IPC System V 消息队列
    Linux IPC System V 共享内存
    ipcs, ipcrm
  • 原文地址:https://www.cnblogs.com/wzxbeliever/p/11709082.html
Copyright © 2011-2022 走看看