1. 程式人生 > >2016-2017 ACM-ICPC Northeastern European Regional Contest (NEERC 16)

2016-2017 ACM-ICPC Northeastern European Regional Contest (NEERC 16)

tor ont freopen n) 物理 sca scanf 圖片 can

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"); }
View Code

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;
}
View Code

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;
}
View Code

2016-2017 ACM-ICPC Northeastern European Regional Contest (NEERC 16)