1 2 3 0.6 0.3 0.4 0.3 0.7 0.9
Case #1: 2.20000
ACM开赛在即,没有模板是决然混不下去的(Q:有模板就混得下去吗?A:Think More,,,)
So, 这是我有生之年(喂!)写得第一份模板。
说说题目,本题有n位学生和m道题,要求在任一中途时刻任2名学生做题差不超过2(防抱大腿麽,,),问解题数期望。
易证每n道题必为n位学生各做一道(1-n的全排列),故可分成ceil((double)m/(double)n),分别求即可
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<functional> #include<iostream> #include<cmath> #include<cctype> #include<ctime> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=pre[x];p;p=next[p]) #define MAXT (200+10) #define MAXN (2000+10) #define MAXM (12000*2+10) #define INF (2139062143) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define eps 1e-6 int T; double a[10+10][1000+10]; class feiyongliu { public: int n,s,t; int q[10000]; int edge[MAXM],next[MAXM],pre[MAXN],weight[MAXM],size; double cost[MAXM]; void addedge(int u,int v,int w,double c) { edge[++size]=v; weight[size]=w; cost[size]=c; next[size]=pre[u]; pre[u]=size; } void addedge2(int u,int v,int w,double c){addedge(u,v,w,c),addedge(v,u,0,-c);} bool b[MAXN]; double d[MAXN]; int pr[MAXN],ed[MAXN]; bool SPFA(int s,int t) { For(i,n) d[i]=INF; MEM(b) d[q[1]=s]=0;b[s]=1; int head=1,tail=1; while (head<=tail) { int now=q[head++]; Forp(now) { int &v=edge[p]; if (weight[p]&&d[now]+cost[p]<d[v]) { d[v]=d[now]+cost[p]; if (!b[v]) b[v]=1,q[++tail]=v; pr[v]=now,ed[v]=p; } } b[now]=0; } return fabs(d[t]-INF)>eps; } double totcost; double CostFlow(int s,int t) { while (SPFA(s,t)) { int flow=INF; for(int x=t;x^s;x=pr[x]) flow=min(flow,weight[ed[x]]); totcost+=(double)flow*d[t]; for(int x=t;x^s;x=pr[x]) weight[ed[x]]-=flow,weight[ed[x]^1]+=flow; } return totcost; } void mem(int n,int t) { (*this).n=n; size=1; totcost=0; MEM(pre) MEM(next) } }S; int main() { // freopen("test_contest2.in", "r", stdin); // freopen(".out", "w", stdout); cin>>T; For(t,T) { int n,m; //m:prob n:people cin>>n>>m; For(i,n) { For(j,m) scanf("%lf",&a[i][j]); } double ans=0; For(k,m/n) { S.mem(m+n+2,m+n+2); S.s=1,S.t=1+n+n+1; For(i,n) { S.addedge2(1,i+1,1,0); } For(i,n) For(j,n) S.addedge2(1+i,1+n+j,1,-a[i][j+(k-1)*n]); For(j,n) S.addedge2(1+n+j,S.t,1,0); ans+=S.CostFlow(S.s,S.t); } if (m%n) { S.mem(m+n+2,m+n+2); S.s=1,S.t=1+n+m%n+1; For(i,n) { S.addedge2(1,i+1,1,0); } For(i,n) For(j,m%n) S.addedge2(1+i,1+n+j,1,-a[i][j+m/n*n]); For(j,m%n) S.addedge2(1+n+j,S.t,1,0); ans+=S.CostFlow(S.s,S.t); } printf("Case #%d: %.5lf\n",t,-ans); } return 0; }