zoukankan      html  css  js  c++  java
  • 乌鲁木齐icpc2017网络赛D、I题

    I、用两种颜色给n(<=100)个点的完全图的边染色,使得纯色三角形的个数最少(输出最少个数和任一一种构造方案)

    题解:

      组合极值中的异色角相关知识,异色三角形个数=异色角个数/2,ans=C(n,3)-异色三角形个数。设点i连出去的边中,染第一种颜色的边数为si,则异色角=∑((n-1)-si)*si,由二次函数性质,让si接近(n-1)/2即可。当n为偶数的时候,将点分成两部分,第一种颜色的边呈完全二分图形式;n=4k+1的时候,所有的点排成一个圈,向左右分别连k个;n=4k+3的时候,向左右分别连k个,再让0~k号点连k+1~2*k+1号点,2*k+2~3*k+1号点连3*k+3~4*k+2号点即可。

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    int mapp[600][600];
    int t,n,s,j,ans,du,tp,k;
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            rep(i,0,n-1)
                rep(j,0,n-1)
                    mapp[i][j]=1;
            if (n%2==0)
            {
                rep(i,0,n/2-1)
                    rep(j,n/2,n-1)
                        mapp[i][j]=mapp[j][i]=2;
            }   else
            {
                s=(n-1)/4;
                rep(i,0,n-1)
                    rep(j,i-s,i+s)
                        mapp[i][(j+n)%n]=mapp[(j+n)%n][i]=2;
                if (n%4==3)
                {
                    k=s;
                    rep(i,0,k)
                        mapp[i][i+k+1]=mapp[i+k+1][i]=2;
                    rep(i,2*k+2,3*k+1)
                        mapp[i][i+k+1]=mapp[i+k+1][i]=2;
                }
            }
            rep(i,0,n-1) mapp[i][i]=0;
            ans=n*(n-1)*(n-2)/6;
            tp=0;
            rep(i,0,n-1)
            {
                du=0;
                rep(j,0,n-1) if (mapp[i][j]==2) ++du;
                tp+=du*(n-1-du);
            }
            ans-=tp/2;
            printf("%d
    ",ans);
            rep(i,0,n-1)
            {
                rep(j,0,n-1)
                    printf("%d ",mapp[i][j]);
                printf("
    ");
            }
        }
        return 0;
    }

    D、题目描述有点长,懒得写了

    题解:

      注意到,任何时刻的最佳策略之一一定是走到最左边或者最右边的点,hack它们(假如你先hack了中间的,终究要hack最旁边的。假设hack最旁边的点的时间为t1,由于行进的终点又在中间k处,hack不需要时间,所以哪怕走到最旁边的点,等到t1时间,以后路过中间的哪些点再顺手hack,时间也不会变长),那么只要做一个排序,用左边剩余l个点,右边剩余r个点,当前在左边或右边(0,1)作为状态dp即可,复杂度O(n2)

    Hint:

      开始位置在0处,而且这是一道poj1991的原题

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    const int INF=1000000000;
    int t,n,l,k,ltot,rtot,x,y,tp,ans;
    int dp[2000][2000][2];
    struct port{
        int cd,dist;
    }pl[1010],pr[1010];
    
    bool cmp1(const port &a,const port &b)
    {
        return (a.dist<b.dist) || (a.dist==b.dist && a.cd<b.cd);
    }
    
    bool cmp2(const port &a,const port &b)
    {
        return (a.dist>b.dist) || (a.dist==b.dist && a.cd<b.cd);
    }
    
    int main()
    {
        scanf("%d",&t);
        rep(T,1,t)
        {
            scanf("%d%d%d",&n,&l,&k);
            ltot=rtot=0;
            rep(i,1,n)
            {
                scanf("%d%d",&x,&y);
                if (x<=k)
                {
                    pl[++ltot].cd=y;
                    pl[ltot].dist=x;
                }   else
                {
                    pr[++rtot].cd=y;
                    pr[rtot].dist=x;
                }
            }
            sort(pl+1,pl+ltot+1,cmp1);
            sort(pr+1,pr+rtot+1,cmp2);
            pl[0].dist=pr[0].dist=0;
            rep(i,0,ltot)
                rep(j,0,rtot)
                    dp[i][j][0]=dp[i][j][1]=INF;
            dp[1][0][0]=max(pl[1].dist,pl[1].cd);dp[0][1][1]=max(pr[1].dist,pr[1].cd);
            rep(i,0,ltot)
                rep(j,0,rtot)
                {
                    if (i>0)
                    {
                        tp=max(dp[i-1][j][0]+pl[i].dist-pl[i-1].dist,pl[i].cd);
                        dp[i][j][0]=min(dp[i][j][0],tp);
                        tp=max(dp[i-1][j][1]+pr[j].dist-pl[i].dist,pl[i].cd);
                        dp[i][j][0]=min(dp[i][j][0],tp);
                    }
                    if (j>0)
                    {
                        tp=max(dp[i][j-1][1]+pr[j-1].dist-pr[j].dist,pr[j].cd);
                        dp[i][j][1]=min(dp[i][j][1],tp);
                        tp=max(dp[i][j-1][0]+pr[j].dist-pl[i].dist,pr[j].cd);
                        dp[i][j][1]=min(dp[i][j][1],tp);
                    }
    
                    //cout<<i<<" "<<j<<" "<<dp[i][j][0]<<" "<<dp[i][j][1]<<endl;
                }
            ans=min(dp[ltot][rtot][0]+k-pl[ltot].dist,dp[ltot][rtot][1]+pr[rtot].dist-k);
            printf("Case #%d: %d
    ",T,ans);
        }
        return 0;
    }
  • 相关阅读:
    sfzwapp2
    linux-umount时提示device is busy时,如何查找被何进程占用?
    MySQL管理_数据库启动与关闭
    cache 比free 多
    NFS
    mysql备份多个库
    liunx修改时区,UTC 修改到CST
    mongodb备份恢复
    嵌入式新闻早班车-第24期
    【STM32H7的DSP教程】第48章 STM32H7的中值滤波器实现,适合噪声和脉冲过滤(支持逐个数据的实时滤波)
  • 原文地址:https://www.cnblogs.com/terra/p/7613303.html
Copyright © 2011-2022 走看看