codeforces1271D 2100分贪心

狂风中的少年 提交于 2020-02-15 06:55:00

题目传送门

题意:

n个城堡,m条单向边,单向边的方向永远是下标大的城堡到下标小的城堡。

初始时你的军队有k个士兵。

现在你依次占领n个城堡,占领顺序是先占领下标小的城堡,再占领下标大的城堡。

占领第 

 个城堡,需要拥有 

 个士兵,但是并不消耗士兵。占领第 

 个城堡后,你的军队会新增 

 个士兵。

保卫第 

 个城堡会获得 

 个金币。

保卫一个城堡需要把一个士兵留在该城堡。

军队的移动顺序是下标小的城堡到下标大的城堡,不会反向移动。

当你在第 

 个城堡时,你可以派一个士兵保卫第 

 个城堡。

当你在第 

 个城堡时,你可以派一个士兵保卫第 

 个城堡。要求必须存在第 

 个城堡到第 

 个城堡的单向边。

一个士兵保卫城堡就会离开军队。

如果不能占领所有城堡,那就输出-1。

问你在占领所有城堡后最多能获得多少个金币。

数据范围:

题解:

需要观察到2个切入点才能解决。

切入点1:如果要把一个士兵安排到第 

 个城堡,那么一定要保证能占领后面所有的城堡。

切入点2:如果要把一个士兵安排到第 

 个城堡,那么一定是合法的最靠后的城堡向第 

 个城堡派士兵。

因此,每个城堡都对应一个可向自身派遣士兵的最靠后的城堡。

依次保卫金币数最多的城堡即可。保卫该城堡后,要满足可以占领所有城堡。

感受:

set用错,直接调了两个小时bug。

欲哭无泪。

代码:

#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int maxn = 5005 ;
const int maxm = 1e6 + 5 ;
const ll mod = 998244353 ;
int n , m , k ;
int f[maxn] , now[maxn] , suf[maxn] ;
int a[maxn] , b[maxn] , c[maxn] ;
struct node
{
	int x , y ;
	bool operator <(const node &s) const
	{
		if(y != s.y)  return y > s.y ;
		else  return y == s.y ;
	}
} ;
set<node> s ;
bool no()
{
    int sum = k ;
	for(int i = 1 ; i <= n ; i ++)
	{
		if(sum < a[i])  return 1 ;
		else  sum += b[i] ;
	}
	return 0 ;
}
void solve()
{
	int ans = 0 ;
	for(auto v : s)
	{
		int u = f[v.x] ;
		bool flag = 0 ;
		for(int i = u ; i <= n ; i ++)
		  if(now[i] - 1 < suf[i + 1]){flag = 1 ; break ;} 
		if(!flag)  
		{
		   for(int i = u ; i <= n ; i ++)	now[i] -- ;
		   ans += v.y ;
		}
	}
	printf("%d\n" , ans) ;
}
int main()
{
	scanf("%d%d%d" , &n , &m , &k) ;
	for(int i = 1 ; i <= n ; i ++)
	  scanf("%d%d%d" , &a[i] , &b[i] , &c[i]) ;
	for(int i = 1 ; i <= n ; i ++)  f[i] = i ;
	for(int i = 1 ; i <= m ; i ++)
	{
		int u , v ;
		scanf("%d%d" , &u , &v) ;
		f[v] = max(f[v] , u) ;
	}
	for(int i = n ; i >= 1 ; i --) 
	  suf[i] = max(a[i] , suf[i + 1] - b[i]) ;
	if(no()){printf("-1\n") ; return 0 ;}
	now[0] = k ;
	for(int i = 1 ; i <= n ; i ++)  now[i] = now[i - 1] + b[i] ;
	for(int i = 1 ; i <= n ; i ++)  s.insert(node{i , c[i]}) ;
	solve() ;
	return 0 ;
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!