zoukankan      html  css  js  c++  java
  • 2019 ICPC南京网络赛 F题 Greedy Sequence(贪心+递推)

    计蒜客题目链接:https://nanti.jisuanke.com/t/41303

    题目:给你一个序列a,你可以从其中选取元素,构建n个串,每个串的长度为n,构造的si串要满足以下条件,

    1. si[1]=i .  

    2. si[j]<si[j-1]

    3. |pos[j] -pos[j-1]|<=k 并且每个a中的元素只能用一次 

    4. 两个串大小的定义时 前k项相等的前提(k和前面不是一个),Ck>Dk,则C大于D

    求Si的长度,并输出

    由于Si[ j ] < Si[j - 1] ,所以在(pos[i] - k , pos[ i ] + k)的区间内如果能找到 Si[ i - 1 ] ,则一定可以通过Si[ i - 1] 找到 Si[ i - 2](即连接Si[i - 1] 的串),直到找到Si的最后一个元素,这意味着在一组序列a中,任何一个元素后续所能连接的元素都是一定的。以S5为例,倒着遍历,从4开始递减到1,如果这之中有数字满足在(pos[i] - k , pos[ i ] + k)的区间,那么直接可以让此元素连接的串拼接至S5[ 1 ]后面,所以题目可以从S1开始递推、记录,就像并查集一样合并,直至Sn,就可以解答。具体看代码。

    AC代码:

    #include<iostream>
    #include<vector>
    #include<queue>
    #include<algorithm>
    #include<set>
    #include<cstring>
    #include<map> 
    #define inf 0x3f3f3f3f
    using namespace std;
    int a[100005];
    int main(){
    	int t;
    	scanf("%d",&t);
    	while(t--){
    		int n,k;
    		map<int,int>m;
    		scanf("%d%d",&n,&k);
    		vector<int> v(n+1);
    		for(int i = 1;i<=n;i++){
    			scanf("%d",&a[i]); 
    			m[a[i]] = i;//存储a[i]的pos 
    			v[a[i]] = 1;//初始化,每个s[i]当前的长度都为1 
    		}
    		for(int i = 2;i<=n;i++){
    			for(int j = i-1;j>0;j--){
    				if(abs(m[i]-m[j]) <= k){//如果满足题目条件 
    					v[i]+=v[j];//拼接,s[i]的长度加上区间内最大元素对应串的长度 ,贪心思想。 
    					break;//打破循环 ,此为s[i]的长度 
    				}
    			}
    		}
    		for(int i = 1;i<=n;i++){
    			if(i == 1){
    				printf("%d",v[i]);
    			}
    			else{
    				printf(" %d",v[i]);
    			}
    		}
    		printf("
    ");
    	}
    	return 0;
    }
    
  • 相关阅读:
    《算法导论》读书笔记(五)
    《算法导论》读书笔记(四)
    《算法导论》读书笔记(三)
    《算法导论》读书笔记(二)
    《算法导论》读书笔记(一)
    Posix消息队列
    管道和FIFO
    linux内核数据结构之kfifo
    linux内核数据结构之链表
    Mybatis XML 映射配置文件 -- 熟悉配置
  • 原文地址:https://www.cnblogs.com/AaronChang/p/12129630.html
Copyright © 2011-2022 走看看