和上一篇一样是论文题。
好难想啊,一眼过去就是网络流TAT果断做不出来
不过好像这种题一般都是网络流或者差分约束(蒟蒻见的题少)
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; struct Edge{int to,next,v;}e[200005]; int head[25],cnt; void ins(int u,int v,int w){ e[++cnt]=(Edge){v,head[u],w};head[u]=cnt; } bool inq[25]; int in[25],d[25]; bool spfa(){ memset(d,0x3f,sizeof(d)); memset(in,0,sizeof(in)); memset(inq,0,sizeof(inq)); d[0]=0;queue<int>q;q.push(0);in[0]=1; while(!q.empty()){ int u=q.front();q.pop(); inq[u]=0; for(int i=head[u];i;i=e[i].next){ int v=e[i].to; if(d[v]>d[u]+e[i].v){ d[v]=d[u]+e[i].v; if(!inq[v]){ if(++in[v]==25)return true; inq[v]=true; q.push(v); } } } } return false; } int w[25],r[25]; void build(int ans){ memset(head,0,sizeof(head));cnt=0; for(int i=1;i<=24;i++){ ins(i,i-1,0);ins(i-1,i,w[i]); } for(int i=8;i<=24;i++) ins(i,i-8,-r[i]); for(int i=1;i<8;i++) ins(i,i+16,ans-r[i]); ins(24,0,-ans); } int main(){ //freopen("a.in","r",stdin); //freopen("a.out","w",stdout); int T;scanf("%d",&T); while(T--){ for(int i=1;i<=24;i++)scanf("%d",&r[i]); int l=0,r,n;scanf("%d",&n); memset(w,0,sizeof(w)); for(int i=1;i<=n;i++){ int x;scanf("%d",&x);w[++x]++; } build(n); if(spfa()){ puts("No Solution"); continue; } r=n; while(l<=r){ int mid=l+r>>1; build(mid); if(spfa())l=mid+1; else r=mid-1; } printf("%d\n",r+1); } return 0; }