- 首先可以观察得出: 如果可以defence 城堡i有多个城市,那么选择最后一个城市再考虑是否defence该城堡是最优方案
- 第一种方法 可以采用dp 因为发现士兵数量C 小于5000 所以设置dp[i]表示攻打到当前城堡时,士兵数剩余i个所取得的最大贡献
- 第二种方法 可以用优先队列优化
- 要求出第i个城市最多可以使用多少个额外的士兵非常的麻烦
- 可以用反悔贪心法
- 如果能占领城市那么就去占领, 如果攻打下一个城市缺人, 那么可以将之前派去的士兵召集回来
- 用一个小顶堆存放派去的士兵,这样如果召回的话损失也最小
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int inf=0x3f3f3f3f; const int N=5e5+100; int dp[6000],a[N],b[N],c[N]; vector<int>contribution[N]; int last[N]; int main () { int n,m,k; cin>>n>>m>>k; for(int i=1;i<=n;i++) { scanf("%d%d%d",&a[i],&b[i],&c[i]); last[i]=i; } int u,v; while(m--) { scanf("%d%d",&u,&v); last[v]=max(last[v],u); } for(int i=1;i<=n;i++) contribution[last[i]].push_back(c[i]); memset(dp,-1,sizeof dp); dp[k]=0; for(int i=1;i<=n;i++) { for(int j=0;j<a[i];j++) dp[j]=-1; for(int j=5500;j>=b[i];j--) dp[j]=dp[j-b[i]]; for(auto &v:contribution[i]) for(int j=0;j<=5500;j++) if(dp[j+1]!=-1) dp[j]=max(dp[j],dp[j+1]+v); } cout<<*max_element(dp,dp+5500); }
dp
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=3e5+10; int a[N],b[N],c[N],last[N]; vector<int>contribution[N]; int main() { int n,m,k; cin>>n>>m>>k; for(int i=1;i<=n;i++) scanf("%d%d%d",&a[i],&b[i],&c[i]),last[i]=i; int u,v; while(m--) scanf("%d%d",&u,&v),last[v]=max(last[v],u); for(int i=1;i<=n;i++) contribution[last[i]].push_back(c[i]); priority_queue<int ,vector<int>, greater<int> >q; int sum=k,ans=0; for(int i=0;i<=n;i++) { sum+=b[i]; for(auto &v:contribution[i]) sum--,q.push(v); while(!q.empty()&&sum<a[i+1]) sum++,q.pop(); if(sum<a[i+1]) printf("-1"),exit(0); } while(!q.empty()) ans+=q.top(),q.pop(); cout<<ans; }
贪心
原文地址:https://www.cnblogs.com/bxd123/p/12076644.html
时间: 2024-11-04 18:11:27