zoukankan      html  css  js  c++  java
  • zoj3997网络流+数学

    题目大意就是每个人都有自己喜欢的座位编号,喜欢的编号是要x的倍数就好,(1<=x<=10)一共10种情况,每种情况的人的数目不一样。

    给你一个n,代表有编号1-n这n个座位,问最多能满足多少人的喜爱要求。

    lcm(1...10)=2520    x跟k*lcm+x的因子情况是一样的(对于1-10这十个数来说) 因为显然k*lcm可以提出x的任意因子,而若不是x的因子,后面+x提一下会出现小数显然就不满足情况了 ,所以是完全一样的。。那么只要预处理出来1-2520的因子情况就可以了。。

    然后就随便跑跑网络流就可以了。。。。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=111;
    int q[N],head[N],tot,S,T,dis[N];
    struct node{
        int to,next,w;
    }e[N<<4];
    void add(int u,int v,int w){
        e[tot].to=v;e[tot].next=head[u];e[tot].w=w;head[u]=tot++;
        e[tot].to=u;e[tot].next=head[v];e[tot].w=0;head[v]=tot++;
    }
    bool bfs(){
        int l=0,r=0;
        q[r++]=S;
        memset(dis,-1,sizeof(dis));
        dis[S]=0;
        while(l<r) {
            int u=q[l++];
            for(int i=head[u];~i;i=e[i].next){
                int v=e[i].to;
                if(dis[v]==-1&&e[i].w>0) {
                    dis[v]=dis[u]+1;
                    q[r++]=v;
                    if(v==T) return true;
                }
            }
        }
        return false;
    }
    int dfs(int s,int low){
        if(!low||s==T) return low;
        int ans=low,a;
        for(int i=head[s];~i;i=e[i].next){
            int v=e[i].to;
            if(e[i].w>0&&dis[v]==dis[s]+1&&(a=dfs(v,min(ans,e[i].w)))) {
                ans-=a;
                e[i].w-=a;
                e[i^1].w+=a;
                if(!ans) return low;
            }
        }
        if(low==ans) dis[s]=-1;
        return low-ans;
    }
    int vis[1<<11],mark[2800],lim[88],p[88];
    void init(){
        int cont=0;
        for(int i=0;i<2520;++i) {
            int S=0;
            for(int j=1;j<=10;++j)  if(i%j==0) S|=1<<j;
            if(!vis[S]) vis[S]=++cont,p[cont]=S;
            mark[i]=vis[S];
        }
    }
    int main(){
        init();
        int Ta,n,x;
        for(scanf("%d",&Ta);Ta--;){
            tot=0;
            memset(head,-1,sizeof(head));
            memset(lim,0,sizeof(lim));
            scanf("%d",&n);
            S=0,T=59;
            for(int i=0;i<2520;++i) {
                int now=n/2520;
                if(i&&n%2520>=i) ++now;
                lim[mark[i]]+=now;
            }
            for(int i=1;i<=48;++i) add(i+10,T,lim[i]);
            for(int i=1;i<=10;++i) {
                scanf("%d",&x);
                if(x) {
                    add(S,i,x);
                    for(int j=1;j<=48;++j) if(p[j]&(1<<i)) add(i,j+10,x);
                }
            }
            int ans=0;
            while(bfs()) ans+=dfs(S,1e9+7);
            printf("%d
    ",ans);
        }
    } 
  • 相关阅读:
    POJ 1015 Jury Compromise【DP】
    POJ 1661 Help Jimmy【DP】
    HDU 1074 Doing Homework【状态压缩DP】
    HDU 1024 Max Sum Plus Plus【DP,最大m子段和】
    占坑补题。。最近占的坑有点多。。。
    Codeforces 659F Polycarp and Hay【BFS】
    Codeforces 659E New Reform【DFS】
    Codeforces 659D Bicycle Race【计算几何】
    廖大python实战项目第四天
    廖大python实战项目第三天
  • 原文地址:https://www.cnblogs.com/mfys/p/8232644.html
Copyright © 2011-2022 走看看