zoukankan      html  css  js  c++  java
  • P1484 种树 经典反悔贪心

    P1484 种树 经典反悔贪心

    题意

    直线上有(n)个坑,这(n)个坑都可以种树,至多可以种(k)棵树,且不能在相邻的坑种树,每个坑位都有一个获利值,求怎样种可以让获利最大。

    [1 leq n leq 5e5\ k leq n / 2\ -1e6 leq w_i leq 1e6 ]

    分析

    容易想到的DP做法:(dp[i][j])表示前(i)棵树,种了(j)棵的最大获利。

    [dp[i][j] = max(dp[i - 1][j],dp[i - 2][j - 1] + w[i]) ]

    这样的DP是(n^2)的,当然,据说可以用WQS二分来优化。

    但是此题也是经典的反悔贪心:

    容易想到,每三个位置,要么选中间的,要么选两边的,可是贪心的选择较大的不一定是最优解。

    维护策略:维护一个大顶堆,每次取出一个点时,同时加入一个点,这个点的权值是左边权值+右边权值-当前权值,同时删除两边的点,(用双向链表维护即可)这样就让后悔机制自洽了。

    复杂度O(nlogn)

    代码

    #include<bits/stdc++.h>
    #define pii pair<ll,int>
    #define eps 1e-7
    #define equals(a,b) (fabs(a - b) < eps)
    #define fi first
    #define se second
    using namespace std;
    typedef long long ll;
    
    const int maxn = 5e5 + 5;
    const ll MOD = 1e9 + 7;
    
    ll rd(){
    	ll x = 0;
    	int f = 1;
    	char ch = getchar();
    	while(ch < '0' || ch > '9'){
    		if(ch == '-')  f = -1;
    		ch = getchar();
    	}
    	while(ch >= '0' && ch <= '9'){
    		x = x * 10 + ch - '0';
    		ch = getchar();
    	}
    	return x * f;
    }
    
    
    struct P{
    	ll val;
    	int l,r;
    };
    
    P p[maxn];
    bool vis[maxn];
    priority_queue<pii> q;
    
    void del(int x){
    	p[x].l = p[p[x].l].l;
    	p[x].r = p[p[x].r].r;
    	p[p[x].l].r = x;
    	p[p[x].r].l = x; 
    }
    
    int main(){
    	int n = rd();
    	int m = rd();
    	for(int i = 1;i <= n;i++){
    		p[i].val = rd();
    		p[i].l = i - 1;
    		p[i].r = i + 1;
    		q.push(make_pair(p[i].val,i));
    	}
    	ll res = 0;
    	while(m--){
    		while(vis[q.top().se]) 
    			q.pop();
    		pii u = q.top();
    		q.pop();
    		if(u.fi <= 0) break;
    		res += u.fi;
    		vis[p[u.se].l] = vis[p[u.se].r] = 1;
    		p[u.se].val = p[p[u.se].l].val + p[p[u.se].r].val - p[u.se].val;
    		q.push(make_pair(p[u.se].val,u.se));
    		del(u.se);
    	}
    	cout << res;
    }
    
  • 相关阅读:
    静态(static)、虚拟(virtual)、动态(dynamic)或消息处理(message)
    SQLLITE
    SQLite数据表和视图
    SQLite
    DELPHI 泛型
    indy10 学习2
    indy10 线程池
    indy
    Indy10 控件的使用(2)TidTCpServer组件学习
    Socket心跳包机制
  • 原文地址:https://www.cnblogs.com/hznumqf/p/14464120.html
Copyright © 2011-2022 走看看