标签:alt closed img 费用流 str pre test i++ iostream
D:上下界费用流
将每个点和每个长度D的区间看作边,限制条件看作流量上下界,差分建图,无源汇最大费用费用流,非常巧妙的使用了差分建图。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<queue> #define N 100003 #define inf 2000000000 #define LL long long using namespace std; const LL INF=1e17; int tot,nxt[N],point[N],v[N],remain[N],can[N],last[N],n,k,t1,t2,a[N],b[N]; LL cost[N],dis[N],ans; void add(int x,int y,int z,LL k) { tot++; nxt[tot]=point[x]; point[x]=tot; v[tot]=y; remain[tot]=z; cost[tot]=k; tot++; nxt[tot]=point[y]; point[y]=tot; v[tot]=x; remain[tot]=0; cost[tot]=-k; } int addflow(int s,int t) { int ans=inf; int now=t; while (now!=s) { ans=min(ans,remain[last[now]]); now=v[last[now]^1]; } now=t; while (now!=s) { remain[last[now]]-=ans; remain[last[now]^1]+=ans; now=v[last[now]^1]; } return ans; } bool spfa(int s,int t) { for (int i=1;i<=t;i++) dis[i]=INF,can[i]=0;; dis[s]=0; can[s]=1; queue<int> p; p.push(s); while (!p.empty()) { int now=p.front(); p.pop(); can[now]=0; for (int i=point[now];i!=-1;i=nxt[i]) if (remain[i]&&dis[v[i]]>dis[now]+cost[i]){ dis[v[i]]=dis[now]+cost[i]; last[v[i]]=i; if (!can[v[i]]) { can[v[i]]=1; p.push(v[i]); } } } if (dis[t]==INF) return false; int flow=addflow(s,t); ans+=dis[t]; return true; } int main() { freopen("delight.in","r",stdin); freopen("delight.out","w",stdout); scanf("%d%d%d%d",&n,&k,&t1,&t2); LL sum=0; tot=-1; memset(point,-1,sizeof(point)); for (int i=1;i<=n;i++) scanf("%d",&a[i]),sum+=(LL)a[i]; for (int i=1;i<=n;i++) scanf("%d",&b[i]); int mn=t2; int mx=k-t1; int S=n+1; int SS=S+1; int TT=SS+1; for (int i=1;i<=n;i++) add(i,i+k>n?TT:i+k,1,-(b[i]-a[i])); for (int i=1;i<=n;i++) add(i,i+1>n?TT:i+1,mx-mn,0); for (int i=1;i<=k;i++) add(S,i,inf,0); add(SS,S,mx,0); while (spfa(SS,TT)); printf("%lld\n",sum-ans); for (int i=1;i<=2*n-1;i+=2) if (remain[i]) printf("E"); else printf("S"); printf("\n"); }
F:概率DP
设dp[i]表示从i这里切一次,i以及i之后w的期望,很容易看出这是可以DP转移的
若i处是w,dp[i]=1/n*∑(∑(sum_c[i..j])+dp[j])否则是:dp[i]=1/n*∑(∑(sum_w[i..j])+dp[j]),维护一下sum_c和sum_w即可
#include <cstdio> #include <cstdlib> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <vector> #include <string> #include <map> using namespace std; double sum[1000010],dp[1000010]; char str[1000010]; int n; int main() { freopen("foreign.in","r",stdin); freopen("foreign.out","w",stdout); int i; scanf("%s",str); n=strlen(str); for(i=0;i<n;i++) { if(str[i]==‘C‘) sum[i]=1.0; } for(i=n-1;i>=0;i--) sum[i]+=sum[i+1]; double sum_c=0.0,sum_w=0.0,cnt=0.0; if(str[n-1]==‘C‘)sum_c=1.0; else sum_w=1.0; for(i=n-2;i>=0;i--) { if(str[i]==‘C‘) { dp[i]=(cnt+sum_w)/(double)(n-i); sum_c+=(double)(n-i); } else { dp[i]=(cnt+sum_c)/(double)(n-i); sum_w+=(double)(n-i); } //cout<<dp[i]<<endl; cnt+=dp[i]; } printf("%.10lf\n",dp[0]); //cout<<dp[0]<<endl; return 0; }
J:物理题
用求重心的公式强行算即可,n^2的复杂度根本不虚
#include <cstdio> #include <cstdlib> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <vector> #include <string> #include <map> const double eps=1e-10; using namespace std; struct zx { double x,y; }; zx zx_all[5010],zx_a[5010]; int n,w,h,m; int vis[5010][5010]; int num[5010]; double le[5010],ri[5010]; int main() { freopen("jenga.in","ri",stdin); freopen("jenga.out","w",stdout); int i,j; scanf("%d%d%d%d",&n,&w,&h,&m); int l,k; num[h+1]=0; for(i=h;i>=1;i--) { le[i]=0; ri[i]=n*w; num[i]=num[i+1]+n; zx_all[i].x=zx_a[i].x=(double)(n*w)/2.0; zx_all[i].y=zx_a[i].y=(double)(n*w)/2.0; } int ans=-1; for(i=1;i<=m;i++) { scanf("%d%d",&l,&k); if(ans!=-1) continue; vis[l][k]=1; for(j=l;j>=1;j--) { num[j]--; if(num[j]==num[j+1]||num[h]==0) { ans=i; break; } } if(ans!=-1) continue; if(num[l]==num[l+1]) { ans=i; break; } else { for(j=1;j<=n;j++) { if(!vis[l][j]) { le[l]=(double)(j-1)*w; break; } } for(j=n;j>=1;j--) { if(!vis[l][j]) { ri[l]=(double)j*w; break; } } } double temp=0; double tmp=0; for(j=1;j<=n;j++) { if(!vis[l][j]) { temp+=((j-1)*w+w/2); tmp+=1.0; } } temp/=tmp; if(l%2==1) { zx_a[l].x=temp; } else { zx_a[l].y=temp; } for(j=l;j>=1;j--) { zx_all[j].x=(zx_all[j+1].x*num[j+1]+zx_a[j].x*(num[j]-num[j+1]))/num[j]; zx_all[j].y=(zx_all[j+1].y*num[j+1]+zx_a[j].y*(num[j]-num[j+1]))/num[j]; if(j!=h&&(j&1)&&((zx_all[j+1].x<=le[j]||zx_all[j+1].x>=ri[j])||(fabs(zx_all[j+1].x-le[j])<eps)||(fabs(zx_all[j+1].x-ri[j])<eps))) { ans=i; break; } else if(j!=h&&!(j&1)&&((zx_all[j+1].y<=le[j]||zx_all[j+1].y>=ri[j])||(fabs(zx_all[j+1].y-le[j])<eps)||(fabs(zx_all[j+1].y-ri[j])<eps))) { ans=i; break; } } } if(ans==-1) { puts("no"); } else { puts("yes"); printf("%d\n",ans); } return 0; }
2016-2017 ACM-ICPC Northeastern European Regional Contest (NEERC 16)
标签:alt closed img 费用流 str pre test i++ iostream
原文地址:https://www.cnblogs.com/Hetui/p/9307919.html