#贪心# [jzoj 3845] 【NOIP2014八校联考第1场第1试9.20】简单题

题目

dzy 手上有一张n 个点m 条边的联通无向图,仙人掌是一张每条边最多在一个简单环内的联通无向图。他想求这个无向图的生成仙人掌中最多有多少条边。
但是dzy 觉得这个问题太简单了,于是他定义了“美丽的生成仙人掌”,即在一个生成仙人掌中如果满足对于任意编号为i,j(i < j) 的两点,存在一条它们之间的简单路径上面有j-i+1 个点,则这个仙人掌是美丽的。
他现在想要知道这张图的美丽的生成仙人掌中最多有多少条边,你能帮帮他吗?


解题思路

显而易见,每一条非链边对应了链上的一个区间。于是问题就变成了选出最多数量
的线段使得其互不相交。

可以设在 i i i节点最多放的边数 f [ i ] f[i] f[i]
f [ i ] = m a x ( f [ g [ i ] ] + 1 , g [ i ] ) ; f[i]=max(f[g[i]]+1,g[i]); f[i]=max(f[g[i]]+1,g[i]);
g [ i ] g[i] g[i]是当前节点最近可连向前面的点。


代码

#include
#include
using namespace std; 
const int N=2e5+10; 
int n,m,f[N],g[N]; 
int main(){
	scanf("%d%d",&n,&m); 
	for(int i=1,t,x,y;i<=m;i++){
		scanf("%d%d",&x,&y); 
		if(x>y) swap(x,y); 
		if(x<y-1) g[y]=max(g[y],x); 
	}
	for(int i=1;i<=n;i++)
		if (g[i]) f[i]=max(f[i-1],f[g[i]]+1); else f[i]=f[i-1]; 
	printf("%d",f[n]+n-1);
}

你可能感兴趣的:(动态规划(/线性DP),贪心算法)