zoukankan      html  css  js  c++  java
  • CXMS 胡策2

    T1: 

    .Double color chessboard
    程序名称:dcc.pas/c/cpp
    时间限制:2000ms
    空间限制:8MB
    题目描述
    有一个游戏:给出一个n行n列的棋盘,里面有n*n个方格,其中每个格子上有颜色,总共
    两种颜色0和1。
    Bob要遵循规则去玩:一张卡要正好覆盖两个相邻且同色的正常格子。
    我们的任务是帮助Bob知道棋盘在上述规则下能覆盖多少格子。
    输入格式
    第1行:整数n表示棋盘的长和宽。
    第2行到第n+1行,有n个数,表示棋盘颜色。
    输出格式
    一个整数,表示能覆盖多少格子。
    n<=300
    题目

    坑点在于8M的空间,表示用一个unsigned short 和 char 代替 int 网络流跑。

    发现wa了,原因在于二分图转流的时候不是加无向边。

    #include<bits/stdc++.h>
    #define us unsigned short
    #define ma 60000
    #define p(x,y) ((x)*301+(y)-1)
    using namespace std;
    struct Node{
        us x; char op;
        int into() {return op*ma+x;}
        void out(int xx){op=xx/ma;x=xx%ma;}
    };
    struct Maxflow{
        #define N 97007
        #define M 541007  
        #define eho(x) for(int i=head[x].into();i;i=net[i].into())
        #define Eho(x) eho(x)
        #define inf 50007
        int tim;
        int p[M];
        Node fall[M],net[M],head[N],que[N];
        int n,tot,s,t,be,ed,gap[N],d[N],x,ret;
        unsigned char cost[M];
        Maxflow() {tot=1;}
        inline void add(int x,int y,int z){
            fall[++tot].out(y); net[tot]=head[x]; head[x].out(tot); cost[tot]=z;
        }
        inline void Adds(int x,int y,int z){
            add(x,y,z); add(y,x,z);
        }
        inline void adds(int x,int y,int z){
            add(x,y,z); add(y,x,0);
        }
        void init() {
            ++gap[d[t]=1];
            que[be=ed=1].out(t);
            while (be<=ed) {
                x=que[be++].into();
                eho(x) if (!d[fall[i].into()]) ++gap[d[fall[i].into()]=d[x]+1],que[++ed]=fall[i]; 
            }
        }
        us get(int x,int fl){
            if (x==t) return fl; if (!fl) return 0;
            p[x]=tim;
            int flow=0,tmp;
            Eho(x) if (d[x]==d[fall[i].into()]+1&&(tmp=get(fall[i].into(),min(fl,(int)cost[i])))) {
                flow+=tmp; fl-=tmp; cost[i]-=tmp; cost[i^1]+=tmp; 
                if (!fl) return flow;
            }
            if (!(--gap[d[x]])) d[s]=n+1;
            ++gap[++d[x]];
            return flow; 
        }
        int isap(int S,int T,int Siz){
            s=S; t=T; n=Siz; init();
            ++tim; ret=get(s,inf);
            while (d[s]<=n) ++tim,ret+=get(s,inf);
            return ret;
        }
    }G;
    int s=p(301,0),t=p(301,1),xx;
    int n; bitset<307> a[307];
    signed main () {
        freopen("dcc.in","r",stdin);
        freopen("dcc.out","w",stdout);
        scanf("%d",&n);
        for (int i=1;i<=n;i++)
         for (int j=1;j<=n;j++) scanf("%d",&xx),a[i][j]=xx;
        for (int i=1;i<=n;i++)
         for (int j=1;j<=n;j++) {
             if ((i+j)&1) {
              G.adds(s,p(i,j),1); 
              if (j<n&&a[i][j]==a[i][j+1]) G.adds(p(i,j),p(i,j+1),1);
               if (i<n&&a[i][j]==a[i+1][j]) G.adds(p(i,j),p(i+1,j),1); 
            }
             else {
              G.adds(p(i,j),t,1); 
              if (j<n&&a[i][j]==a[i][j+1]) G.adds(p(i,j+1),p(i,j),1);
               if (i<n&&a[i][j]==a[i+1][j]) G.adds(p(i+1,j),p(i,j),1); 
            }
         }
         printf("%d
    ",G.isap(s,t,n*n+3)*2);
    }
    View Code

    T2:

    题目描述
    农场主Bob有无限的奶牛,奶牛分为A,B两种类型。现在Bob要选出N(2≤N≤10
    15)头奶牛,
    并把这N头奶牛围成一个环。为了美观且不单调,Bob希望任意相邻M(2≤M≤5,M≤N)头奶牛中
    有不超过K(1≤K<M)头A类型的奶牛,其余奶牛均为B类型的奶牛。并且Bob想知道总共有多少
    种不同的环。(结果 mod 1000000007)。
    n<=1e15
    题目

    快速幂。

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    const int M=5,p=1000000007;
    LL n,m,k,ans;
    LL f[1<<M],a[1<<M][1<<M];
    int MAX,cnt;
    bool pd[1<<M];
    inline void mulself(LL a[1<<M][1<<M]) {
        LL c[1<<M][1<<M];
        memset(c,0, sizeof c);
        for(int i=0;i<MAX;++i)
            for(int j=0;j<MAX;++j)
                for(int k=0;k<MAX;++k)
                    c[i][j]=(c[i][j]+a[i][k]*a[k][j])%p;
        memmove(a,c,sizeof c);
    }
    inline void mul(LL f[1<<M],LL a[1<<M][1<<M]) {
        static LL c[1<<M];
        memset(c,0,sizeof c);
        for(int j=0;j<MAX;++j)
            for(int k=0;k<MAX;++k)
                c[j]=(c[j]+f[k]*a[k][j])%p;
        memmove(f,c,sizeof c);
    }
    int main() {
        freopen("k.in","r",stdin);
        freopen("k.out","w",stdout);
        scanf("%lld%lld%lld",&n,&m,&k);
        MAX=1<<m;
        for(int i=0;i<MAX;++i) {
            cnt=0;
            for(int j=0;j<m;++j)
                if(i&1<<j) ++cnt;
            if(cnt<=k) pd[i]=true;
        }
        for(int i=0;i<MAX;++i)
            if(pd[i]) {
                memset(f,0,sizeof f);f[i]=1;
                memset(a,0,sizeof a);
                for(int j=0;j<MAX;++j) if(pd[j]){
                    a[j>>1][j]=1;
                    a[(j>>1)+(1<<(m-1))][j]=1;
                }
                for(LL y=n;y;y>>=1,mulself(a)) if(y&1) mul(f,a);
                ans=(ans+f[i])%p;
            }
        printf("%lld
    ",ans);
        return 0;
    }
    View Code

    T3:

     buyef
    程序名称:buyef.pas/c/cpp
    时间限制:2000ms
    空间限制:32MB
    问题描述
    CQH想要潜入女生宿舍,因此他不但需要策划完美的潜入路线,更要购买一些女装进行掩
    饰。
    商店里总共有N(1≤N≤10
    6)件女装,第i件女装的价格为Wi(1≤Wi≤300),萌值为
    Vi(1≤Vi≤10
    9)。
    CQH有一个总预算K(1≤K≤10
    5),他希望知道对于每个[1,k]中的整数i,如果他带了i
    元,能买到的女装的萌值之和最大是多少。由于CQH正在策划路线,这个问题就交给你了。
    输入格式
    第一行N和K。
    接下来N行,每行Wi和Vi。
    输出格式
    第一行K个数,第i个数表示带了i元时的答案。
    20% N≤300100% 1≤N≤1000000
    1≤Wi≤3001≤Vi≤100000
    1≤K≤100000
    题目

    对Wi分组sort,对每个Wi做决策分治。

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    #define pb push_back
    #define N 1001007
    int n,m,w,k,b,lo,o,VV,K;
    vector<LL> v[307];
    LL f[2][N];
    #define sight(c) ('0'<=c&&c<='9')
    inline void read(int &x){
        static char c;
        for (c=getchar();!sight(c);c=getchar());
        for (x=0;sight(c);c=getchar())x=x*10+c-48;
    }
    void write(LL x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);}
    inline void writeln(LL x){ if (x<0) putchar('-'),x*=-1; write(x); putchar('
    '); }
    inline void writel(LL x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); }
    void solve(int l,int r,int L,int R){
        if (l>r) return ;
        int Mid=l+r>>1,d=Mid;
        LL tmp;
        f[o][Mid*k+b]=f[lo][Mid*k+b];
        for (int i=min(R,Mid-1);i>=L;i--) {
            if (Mid-i>v[k].size()) break;
            if ((tmp=f[lo][i*k+b]+v[k][Mid-i-1])>f[o][Mid*k+b]) 
              f[o][Mid*k+b]=tmp,d=i;
        }
        solve(l,Mid-1,L,d); solve(Mid+1,r,d,R);
    }
    int main () {
        freopen("buyef.in","r",stdin);
        freopen("buyed.out","w",stdout);
        read(n); read(m);
        for (int i=1;i<=n;i++){
            read(w); read(VV);
            K=max(K,w);
            v[w].pb(VV);
        }
    //    cerr<<"rrsb"<<K;
        for (int i=1;i<=K;i++)  
         sort(v[i].begin(),v[i].end(),greater<LL>());
    //    cerr<<"rrsb";
        for (int i=1;i<=K;i++) 
         for (int j=1;j<v[i].size();j++) v[i][j]+=v[i][j-1];
        o=1; 
        
        for (k=1;k<=K;k++) {
            if (!v[k].size()) continue;
            for (b=0;b<k;b++) solve(0,(m-b)/k,0,(m-b)/k);
            for (int i=1;i<=m;i++) f[o][i]=max(f[o][i],f[o][i-1]);
            o^=1; lo^=1;
        }
        for (int i=1;i<=m;i++) 
         writel(f[lo][i]);
        return 0;
    }
    View Code
  • 相关阅读:
    ASP.NET学习篇(4)——服务器端的控件【转自www.bitsCN.com】
    sql2005 管道的另一端上无任何进程解决方法
    SQL服务器名称的更改
    如何辨别移动硬盘的好坏
    ADO绑定SQL数据库过程
    SQL变量的使用
    SQL子查询
    什么SQL解发器?
    什么是存储过程呢?
    显式事务和隐式事务之间有什么区别?
  • 原文地址:https://www.cnblogs.com/rrsb/p/9064105.html
Copyright © 2011-2022 走看看