zoukankan      html  css  js  c++  java
  • set so 就

       

    问题 B: 就

    时间限制: 1 Sec  内存限制: 512 MB

    题目描述

    就so.in/.out

    【背景描述】

    一排 N 个数, 第 i 个数是 Ai , 你要找出 K 个不相邻的数, 使得他们的和最大。

    请求出这个最大和。

    【输入格式】

    第一行两个整数 N 和 K。

    接下来一行 N 个整数, 第 i 个整数表示 Ai 。

    【输出格式】

    一行一个整数表示最大和, 请注意答案可能会超过 int 范围

    【样例输入】

    3 2

    4 5 3

    【样例输出】

    7

    【数据范围】

    对于 20% 的数据, N, K ≤ 20 。

    对于 40% 的数据, N, K ≤ 1000 。

    对于 60% 的数据, N, K ≤ 10000 。

    对于 100% 的数据, N, K ≤ 100000 , 1 ≤ Ai ≤ 1000000000。

       考试时大部分人应该都自豪的写出了n*n的DP,能A60分,结果正解是贪心。对,就是贪心,最先选择最大的一个点,明显这不一定是最优解,而且他周围的两个点都没办法选了,而他的值加进了ans无法再踢除。。

       这些问题用一个set+链表就解决了。选了一个点,就把他周围两个点用链表缩成一个,权值赋成左边点权值+右边点权值-自己权值。这个就是用来反悔的。如果选了新的点,相当于向ans里加了A+C-B,而原来ans里加了B,B抵消了,

        就相当于没加。

       

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<set>
    #define ll long long
    #define N 100005
    #define inf 1000000000
    using namespace std;
    ll read()
    {
    	ll sum=0,f=1;char x=getchar();
    	while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();}
    	while(x>='0'&&x<='9'){sum=sum*10+x-'0';x=getchar();}
    	return sum*f;
    }
    struct hh
    {
    	int id;
    	ll h;
    	hh(){}
    	hh(int a,ll b)
    	{
    		h=b;
    		id=a;
    	}
        friend bool operator <(const hh &a,const hh &b)
        {
        	return (a.h!=b.h) ? (a.h>b.h):(a.id<b.id);
    	}
    };
    set<hh> st;
    int nex[N],fro[N],n,k;
    ll ans=0,a[N];  
    int main()
    {
    	freopen("so.in","r",stdin);
    	freopen("so.out","w",stdout);
    	scanf("%d%d",&n,&k);
    	for(int i=1;i<=n;i++)
    	{
    	   scanf("%lld",&a[i]);
    	   nex[i]=i+1;
    	   fro[i]=i-1;	
    	   st.insert(hh(i,a[i]));
    	}a[0]=-1e15;
    	nex[n]=0;
        while(k--)
    	{
    		int x=st.begin()->id;
    		ans+=a[x];
    		a[x]=-a[x];
    		a[x]+=a[fro[x]];
    		a[x]+=a[nex[x]];
    		st.erase(st.begin());
    		st.erase(hh(nex[x],a[nex[x]]));
    		st.erase(hh(fro[x],a[fro[x]]));
    		st.insert(hh(x,a[x]));
    		if(fro[fro[x]])nex[fro[fro[x]]]=x;
    		if(nex[nex[x]])fro[nex[nex[x]]]=x;
    		nex[x]=nex[nex[x]];
    		fro[x]=fro[fro[x]];
    	} 
    	cout<<ans;
    }

  • 相关阅读:
    JMeter分布式压测-常见问题之( Cannot start. localhost.localdomain is a loopback address)
    Jmeter实现multipart/form-data类型请求
    【漫画算法最后章节】【算法运用】 —— Bitmap算法的巧用
    整数类型
    宁波多校(一) E题 ddd的逛街计划(Easy Version)
    宁波多校(一) D题 COLORS的字符串挑战(线段树+hash+二分)
    CF1361D Johnny and James(模拟)
    CF1363F Rotating Substrings(dp)
    CF1363E Tree Shuffling(贪心+树上乱搞)
    AcWing1185 单词游戏(欧拉路径)
  • 原文地址:https://www.cnblogs.com/QTY2001/p/7632736.html
Copyright © 2011-2022 走看看