Topic Portal
Meaning of the questions:
n castles, m unidirectional sides, side-way direction is always at a large scale subscript small castle to the castle.
When your initial k army soldiers.
Now you turn the n occupied castle, the occupation order is occupied subscript small castle, then occupied subscript big castle.
Occupation of castles, need to have soldiers, but soldiers are not consumed. The first occupied after castles, your army will add soldiers.
The first defense of a castle will receive gold coins.
A castle to defend a soldier needs to stay in the castle.
Mobile is the order of the army marked a small castle next to the castle subscript large, does not move backward.
When you are at the time of castles, you can send a soldier to defend the first castles.
When you are at the time of castles, you can send a soldier to defend the first castles. It requires the existence of castles to the second castles unidirectional edge.
A soldier will leave the army to defend the castle.
If you can not occupy all castles, then output -1.
I ask you to get the maximum number of coins after the occupation of all the castle.
Data range: .
。
answer:
We need to observe the two entry points to resolve.
1 entry point: if we want to arrange a soldier of castles, then it must be guaranteed to all occupied castle behind.
2 entry point: if we want to arrange a soldier of castles, then it must be legitimate by most of the castle after the first castles to send soldiers.
Thus, each corresponding to the castle after castle are the most by a dispatch to its own soldiers.
In order to defend the castle to the largest number of gold coins. After defending the castle, to meet all can be occupied castle.
Experience:
set wrong, the direct transfer two hours bug.
Tears.
Code:
#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 ;
}