zoukankan      html  css  js  c++  java
  • P4393 [BOI2007]Sequence 序列问题(链表)

    对于一个给定的序列a1, …, an,我们对它进行一个操作reduce(i),该操作将数列中的元素ai和ai+1用一个元素max(ai,ai+1)替代,这样得到一个比原来序列短的新序列。这一操作的代价是max(ai,ai+1)。进行n-1次该操作后,可以得到一个长度为1的序列。

    我们的任务是计算代价最小的reduce操作步骤,将给定的序列变成长度为1的序列。

    容易发现一个贪心思路:

    每次选最小的数和它两边的数中较小的那个数合并。

    可以将所有的数排序之后用链表O(1)维护。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+10; 
    struct qnode {
    	int w;
    	int p;
    	bool operator < (const qnode &r) const {
    		return w>r.w;	
    	}	
    };
    priority_queue<qnode> q;
    
    int a[maxn];
    int nxt[maxn],pre[maxn];
    int p[maxn];
    int n;
    int b[maxn];
    int cmp (int x,int y) {
    	return a[x]<a[y];
    }
    int main () {
    	scanf("%d",&n);
    	for (int i=1;i<=n;i++) scanf("%d",a+i);
    	for (int i=1;i<=n;i++) {
    		if (i<n) nxt[i]=i+1;
    		if (i>1) pre[i]=i-1;
    		b[i]=i;
    	}
    	sort(b+1,b+n+1,cmp);
    	long long ans=0;
    	for (int i=1;i<=n;i++) {
    		int p=b[i];
    		if (pre[p]&&nxt[p]) {
    			if (a[pre[p]]<a[nxt[p]]) {
    				ans+=a[pre[p]];
    			}
    			else {
    				ans+=a[nxt[p]];
    			}
    			nxt[pre[p]]=nxt[p];
    			pre[nxt[p]]=pre[p];
    		}
    		else if (pre[p]) {
    			ans+=a[pre[p]];
    			nxt[pre[p]]=nxt[p];
    		}
    		else if (nxt[p]) {
    			ans+=a[nxt[p]];
    			pre[nxt[p]]=pre[p];
    		}
    	}
    	printf("%lld
    ",ans);
    }
  • 相关阅读:
    UWP取出图片主色调
    UWP上可用的GB2312编码
    嵌入的资源 和 Resource
    WPF 斜角border
    .net core初试 --- 控制台程序
    Python初学手记----在window系统中安装环境
    我的第一个网络爬虫 C#版 福利 程序员专车
    使用FFMpeg命令行录屏推rtmp流
    WPF制作表示透明区域的马赛克画刷
    WPF之坑——surface触控失灵之谜
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/15039543.html
Copyright © 2011-2022 走看看