传送门:QAQQAQ

题意:$n$个点中选$m$个不相邻的点,使得这些点不相邻(1和n算相邻),求这些点的最大值

思路:这不是神仙题不是神仙题……

刚看到这题觉得不难,好像只要贪心就可以了但贪心不知从何下手——因为取了一个点就会影响其它两个点

所以我们要用“可以反悔”的贪心,即取完一个点以后,我们要加入一个点,让此操作可以反悔——不取这个点,而取它两边的点,即$val[new]=val[l]+val[r]-val[pos]$,然后取了当前点把它左右点删去即可(因为再取一次当前点就是取它左右点的情况)(有点像网络流里的残量网络)

这样用一个堆维护,每次取最大值即可

(证明:因为有可以反悔的操作,所以每种情况都可以选到,不会因为取了当前最大值而排除了全局最优解,而每次取的都是合法的切实最大值,所以最终答案一定是最大值)

代码:(推荐比赛的时候先写一个较为稳妥的DP)

#include<bits/stdc++.h>
using namespace std;
const int inf=(int)2e8;
const int N=; int dp[][][][];
int n,m,a[N],ans=-inf; void checkmax(int &x,int y)
{
if(x<y) x=y;
} void subtask1()
{
for(int bl=;bl<=;bl++)
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)//之前写成了0
for(int t=;t<=;t++) dp[bl][i][j][t]=-inf;
dp[][][][]=a[]; dp[][][][]=;
for(int bl=;bl<=;bl++)
{
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
if(!(i==n&&bl==)) dp[bl][i][j][]=dp[bl][i-][j-][]+a[i];
dp[bl][i][j][]=max(dp[bl][i-][j][],dp[bl][i-][j][]);//+=!
if(j==m)
{
checkmax(ans,dp[bl][i][j][]);
checkmax(ans,dp[bl][i][j][]);
}
}
}
}
printf("%d\n",ans);
} struct node{
int l,r,val,id;
bool operator < (const node &rhs) const{
return val<rhs.val;
}
}t[N]; int vis[N];
priority_queue<node> q;
void subtask2()
{
int sum=;
for(int i=;i<=n;i++)
{
t[i].l=i-; t[i].r=i+;
t[i].val=a[i]; t[i].id=i;
}
t[].l=n; t[n].r=;
for(int i=;i<=n;i++) q.push(t[i]);
for(int i=;i<=m;i++)
{
while(vis[q.top().id]) q.pop();
node f=q.top(); q.pop();
//取出来的node不能直接用,因为它的l,r可能已经改变
vis[t[f.id].l]=vis[t[f.id].r]=;//可以理解成三个点并成了一个点
sum+=f.val;
t[f.id].val=t[t[f.id].l].val+t[t[f.id].r].val-t[f.id].val;
t[f.id].l=t[t[f.id].l].l;
t[f.id].r=t[t[f.id].r].r;
t[t[f.id].r].l=f.id;
t[t[f.id].l].r=f.id;
q.push(t[f.id]);
}
cout<<sum<<endl;
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
if(m>n/)
{
puts("Error!");
return ;
}
if(n<=) subtask1();
else subtask2();
return ;
}

洛谷P1792——[国家集训队]种树的更多相关文章

  1. 洛谷P1792 [国家集训队]种树(链表 贪心)

    题意 题目链接 Sol 最直观的做法是wqs二分+dp.然而还有一种神仙贪心做法. 不难想到我们可以按权值从大到小依次贪心,把左右两边的打上标记,但这显然是错的比如\(1\ 231\ 233\ 232 ...

  2. [洛谷P1792][国家集训队]种树

    题目大意:给出由$n$个数组成的环,取某个数就可以得到它的分数,相邻的两个数不能同时取.问取$m$个数可以得到的最大分数. 题解:建一个大根堆,贪心取,每个点记录前驱后继,取一个点就把前驱后继设成不能 ...

  3. P1792 [国家集训队]种树

    P1792 [国家集训队]种树 题目描述 A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树. 园林部门得到指令后,初步规划出n个种树的位置,顺时针编号1到n.并且每 ...

  4. 模板—点分治A(容斥)(洛谷P2634 [国家集训队]聪聪可可)

    洛谷P2634 [国家集训队]聪聪可可 静态点分治 一开始还以为要把分治树建出来……• 树的结构不发生改变,点权边权都不变,那么我们利用刚刚的思路,有两种具体的分治方法.• A:朴素做法,直接找重心, ...

  5. [洛谷P1527] [国家集训队]矩阵乘法

    洛谷题目链接:[国家集训队]矩阵乘法 题目背景 原 <补丁VS错误>请前往P2761 题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入输出格式 输入 ...

  6. 洛谷P1501 [国家集训队]Tree II(LCT,Splay)

    洛谷题目传送门 关于LCT的其它问题可以参考一下我的LCT总结 一道LCT很好的练习放懒标记技巧的题目. 一开始看到又做加法又做乘法的时候我是有点mengbi的. 然后我想起了模板线段树2...... ...

  7. 洛谷P2619 [国家集训队2]Tree I(带权二分,Kruscal,归并排序)

    洛谷题目传送门 给一个比较有逼格的名词--WQS二分/带权二分/DP凸优化(当然这题不是DP). 用来解决一种特定类型的问题: 有\(n\)个物品,选择每一个都会有相应的权值,需要求出强制选\(nee ...

  8. 洛谷 P1407 [国家集训队]稳定婚姻 解题报告

    P1407 [国家集训队]稳定婚姻 题目描述 我国的离婚率连续7年上升,今年的头两季,平均每天有近5000对夫妇离婚,大城市的离婚率上升最快,有研究婚姻问题的专家认为,是与简化离婚手续有关. 25岁的 ...

  9. 洛谷 P1852 [国家集训队]跳跳棋 解题报告

    P1852 [国家集训队]跳跳棋 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在\(a\),\(b\), ...

随机推荐

  1. python_django_中间件

    什么是中间件? 可以介入django的请求和响应的轻量级的底层插件,它其实就是一个python类,我们在settings配置文件中的↓↓↓↓,都是中间件 MIDDLEWARE = [ 'django. ...

  2. zepto-touch事件

    <!doctype html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. Sql Server 小知识不断扩充中

    1.  char.varchar.nvarchar 区别 char 定长字符数据长度8000字符,小于8000字符时以空格填充. varchar 变长字符数据最大长度8000,小于8000字符时不会以 ...

  4. List之取不同元素

    1.工具-->NuGet包管理器-->管理解决方案的NuGet包程序包 2.添加System.Linq包 3.引用 using System.linq List<int> li ...

  5. smarty基础总结

    前提: 1. 部署smarty模板目录: 2. 编写Smarty类的子类,定制好template_dir.compile_dir.config_dir.cache_dir.left_delimiter ...

  6. 归并排序c语言

    void mergeAdd(int arr[], int left, int mid, int right, int *temp){ int i = left; ; int k = left;//临时 ...

  7. spark在不同环境下的搭建|安装|local|standalone|yarn|HA|

    spark的集群环境安装搭建 1.spark local模式运行环境搭建 常用于本地开发测试,本地还分为local单线程和local-cluster多线程; 该模式被称为Local[N]模式,是用单机 ...

  8. SP2713 GSS4 - Can you answer these queries IV(线段树)

    传送门 解题思路 大概就是一个数很少次数的开方会开到\(1\),而\(1\)开方还是\(1\),所以维护一个和,维护一个开方标记,维护一个区间是否全部为\(1/0\)的标记.然后每次修改时先看是否有全 ...

  9. (转)OC学习笔记 @property的属性 strong 和 weak 理解

    在ObjectiveC里,用@property访问所有的实例变量.@property有一对属性:strong 和 weak.官方文档里的解释晦涩难懂:Stack Overflow里的用户RDC (ht ...

  10. hdu多校第八场 1010(hdu6666) Quailty and CCPC 排序/签到

    题意: CCPC前10%能得金牌,给定队伍解题数和罚时,问你有没有一个队伍如果向上取整就金了,四舍五入就银了. 题解: 排序后按题意求解即可. #include<iostream> #in ...