CF283C Coin Troubles

https://www.luogu.com.cn/problem/CF283C

根据限制关系建图转化为一条条链不难想到。

转化后,先按最小情况填满,即叶子为 0,然后增 1 上去。

考虑让某一个点 +1,那是不是这个点到根的路径上的点都要 +1

于是对于每个点算出来这个贡献做完全背包即可。

#include <bits/stdc++.h> #define int long long #define pb push_back using namespace std; const int mod=(int)(1e9+7),N=305; vector<int>g[N]; int n,m,t,a[N],num[N],du[N],val[N],id[N]; int f[100005]; bool cmp(const int &x,const int &y) { return num[x]<num[y]; } vector<int>vec[N]; queue<int>q; signed main() { cin.tie(0); ios::sync_with_stdio(false); cin>>n>>m>>t; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=m;i++) { int x,y; cin>>x>>y; g[y].pb(x); ++du[x]; } // int tot=0; for(int i=1;i<=n;i++) if(!du[i]) id[i]=i,q.push(i); while(!q.empty()) { int x=q.front(); q.pop(); for(int y:g[x]) { num[y]=num[x]+1; id[y]=id[x]; q.push(y); } } for(int i=1;i<=n;i++) { if(!id[i]) { cout<<"0"; return 0; } } for(int i=1;i<=n;i++) vec[id[i]].pb(i); for(int i=1;i<=n;i++) sort(vec[i].begin(),vec[i].end(),cmp); for(int i=1;i<=n;i++) { int qwq=0; for(int j=0;j<vec[i].size();j++) qwq+=j*a[vec[i][j]]; t-=qwq; for(int j=0;j<vec[i].size();j++) { qwq=0; for(int k=j;k<vec[i].size();k++) qwq+=a[vec[i][k]]; val[vec[i][j]]=qwq; } } if(t<0) { cout<<"0"; return 0; } f[0]=1; for(int i=1;i<=n;i++) { for(int j=val[i];j<=t;j++) { f[j]=(f[j]+f[j-val[i]])%mod; } } cout<<(f[t]%mod+mod)%mod; return 0; } // 不妨考虑假如链上一个点增大1,那么显然这个点到根的路径中的每个点+1 // 所以先对于每条链填满根为 sz-1 // 然后计算每个点+1 带来的贡献 // 完全背包即可 // b>c -> b=c+1,连 (c,b) 入度为0即为0

__EOF__

本文作者F x o r G
本文链接https://www.cnblogs.com/xugangfan/p/16484828.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   FxorG  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示