luoguP1251 餐巾计划问题
Posted shxnb666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luoguP1251 餐巾计划问题相关的知识,希望对你有一定的参考价值。
题目:
https://www.luogu.org/problemnew/show/P1251
题解:
原来的想法不行:算费用的时候算的是一条餐巾的,但对于重复使用多天的餐巾不公平,因为他们的费用肯定比用一次的大,但是它们贡献也大。
两种想法:
->平均费用 不可做。
->这一次费用 可做。
嘿嘿,还挺有意思的。
#include<cstdio> #include<cstring> #include<iostream> #include<vector> #include<queue> #include<cstdlib> #define LL long long #define N 10000 #define INF 1000000007 #define S 0 #define T (2*n+1) #define ri register int using namespace std; int n,cc; int r[N],p0,t1,p1,t2,p2; int cr(int x) return 2*n+x+1; struct graph vector<int> to,w,c; vector<int> ed[N]; LL dis[N]; int cur[N]; bool vis[N]; void add_edge(int a,int b,int aw,int ac) to.push_back(b); w.push_back(aw); c.push_back(ac); ed[a].push_back(to.size()-1); to.push_back(a); w.push_back(0); c.push_back(-ac); ed[b].push_back(to.size()-1); bool spfa() memset(dis,0x2f,sizeof(dis)); memset(vis,0,sizeof(vis)); queue<int> q; dis[S]=0;q.push(S);vis[S]=1; while (!q.empty()) int x=q.front(); q.pop(); //printf("%d %d %lld\n",cc,x,dis[x]); for (ri i=0;i<ed[x].size();i++) int e=ed[x][i]; if (dis[to[e]]>dis[x]+c[e] && w[e]) dis[to[e]]=dis[x]+c[e]; if (!vis[to[e]]) vis[to[e]]=1,q.push(to[e]); vis[x]=0; return dis[T]<INF; int dfs(int x,int lim) if (x==T || !lim) return lim; LL sum=0; vis[x]=1; for (ri &i=cur[x];i<ed[x].size();i++) int e=ed[x][i]; if (dis[x]+c[e]==dis[to[e]] && w[e] && !vis[to[e]]) int f=dfs(to[e],min(lim,w[e])); w[e]-=f; w[1^e]+=f; lim-=f; sum+=f; if (!lim) return sum; return sum; LL zkw() LL ret=0; cc=1; while (spfa()) memset(vis,0,sizeof(vis)); memset(cur,0,sizeof(cur)); int t=dfs(S,INF); ++cc; ret+=t*dis[T]; return ret; G; int main() scanf("%d",&n); for (ri i=1;i<=n;i++) scanf("%d",&r[i]); scanf("%d %d %d %d %d",&p0,&t1,&p1,&t2,&p2); for (ri i=1;i<=n;i++) G.add_edge(S,n+i,r[i],0); for (ri i=1;i<=n;i++) G.add_edge(i,T,r[i],0); for (ri i=1;i<n;i++) G.add_edge(n+i,n+i+1,INF,0); for (ri i=1;i<=n;i++) if (i+t1<=n) G.add_edge(n+i,i+t1,INF,p1); if (i+t2<=n) G.add_edge(n+i,i+t2,INF,p2); for (ri i=1;i<=n;i++) G.add_edge(S,i,INF,p0); printf("%lld\n",G.zkw()); return 0;
以上是关于luoguP1251 餐巾计划问题的主要内容,如果未能解决你的问题,请参考以下文章