bestcoder #70

A:直接枚举就行了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;

ll a,b,c;
ll p,q,k,m;

int main()
{
    //freopen("in.txt","r",stdin);
    int T;cin>>T;
    while(T--){
        scanf("%I64d%I64d%I64d",&a,&b,&c);
        bool flag=0;
        for(p=1;p*p<=a;p++){
            if(a%p) continue;
            q=a/p;
            for(k=1;k*k<=c;k++){
                if(c%k) continue;
                m=c/k;
                if(q*k+m*p==b) flag=1;
                if(q*m+p*k==b) flag=1;
                if(flag) break;
            }
            if(flag) break;
        }
        puts(flag?"YES":"NO");
    }
    return 0;
}
View Code

B:直接dp差值,比赛的时候复杂度估计错,直接写了3^20...

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=2010;
const int INF=1e9+10;

int n,m;
int a[maxn];
int dp[25][maxn];

int main()
{
    //freopen("in.txt","r",stdin);
    int T;cin>>T;
    while(T--){
        scanf("%d",&n);
        int sum=0;
        REP(i,1,n) scanf("%d",&a[i]),sum+=a[i];
        scanf("%d",&m);
        MS0(dp);
        dp[0][0]=1;
        REP(i,1,n){
            REP(j,0,sum){
                if(j+a[i]<=sum) dp[i][j]+=dp[i-1][j+a[i]];
                dp[i][j]+=dp[i-1][abs(j-a[i])];
                dp[i][j]+=dp[i-1][j];
            }
        }
        while(m--){
            int k;scanf("%d",&k);
            puts(dp[n][k]?"YES":"NO");
        }
    }
    return 0;
}
View Code

C:dp,比赛的时候思路是对的,但开了n^3的内存直接超了,居然没能想到滚动数组。。

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#pragma comment(linker, "/STACK:102400000,102400000")
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=502;
const int INF=1e9+10;
const int MOD=5201314;

int n;
char ch[maxn][maxn];
int dp[2][maxn][maxn];
int dx1[]={0,0,-1,-1};
int dx2[]={0,1,0,1};

int main()
{
    //freopen("in.txt","r",stdin);
    int T;cin>>T;
    while(T--){
        scanf("%d",&n);
        memset(dp,-1,sizeof(dp));
        REP(i,1,n){
            scanf("%s",ch[i]+1);
        }
        MS0(dp);
        dp[1][1][n]=(ch[1][1]==ch[n][n]?1:0);
        REP(i,2,n){
            memset(dp[i%2],0,sizeof(dp[i%2]));
            REP(x1,1,i){
                int y1=i+1-x1;
                for(int x2=n;x2>=n+1-i;x2--){
                    int y2=n+1-(i+1-(n+1-x2));
                    if(x1>x2) break;
                    if(ch[x1][y1]!=ch[x2][y2]) continue;
                    REP(k,0,3){
                        int px1=x1+dx1[k];
                        int py1=(i-1)+1-px1;
                        int px2=x2+dx2[k];
                        int py2=n+1-(i-(n+1-px2));
                        if(px1<1||py1<1||px2>n||py2>n) continue;
                        dp[i%2][x1][x2]+=dp[(i+1)%2][px1][px2];
                        dp[i%2][x1][x2]%=MOD;
                    }
                }
            }
        }
        int ans=0;
        REP(i,1,n) ans=(ans+dp[n%2][i][i])%MOD;
        printf("%d
",ans);
    }
    return 0;
}
View Code

D:不会,待补。据说是cdq分治。

E:最小费用最大流。由于要求最小时间,且时间的计算方式类似罚时,比如如果只有4个顾客和1个店员,那么总时间就是t+2t+3t+4t,因此要将每个店员拆成n个点,拆成的第k个点到每个顾客的费用是k*t,大概如下图。。然后求下满流时的最小费用就可以了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<vector>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=100100;
const int INF=1e9+10;

struct Edge
{
    int from,to,cap,flow,cost;
};

struct MCMF
{
    int n,m,s,t;
    vector<Edge> edges;
    vector<int> G[maxn];
    int inq[maxn];
    int d[maxn];
    int p[maxn];
    int a[maxn];
    void init(int n)
    {
        this->n=n;
        REP(i,1,n) G[i].clear();
        edges.clear();
    }
    void addedge(int from,int to,int cap,int cost)
    {
        edges.push_back((Edge){from,to,cap,0,cost});
        edges.push_back((Edge){to,from,0,0,-cost});
        m=edges.size();
        G[from].push_back(m-2);
        G[to].push_back(m-1);
    }
    bool bellman_ford(int s,int t,int &flow,int &cost)
    {
        REP(i,1,n) d[i]=INF;
        MS0(inq);
        d[s]=0;inq[s]=1;p[s]=0;a[s]=INF;
        queue<int> q;
        q.push(s);
        while(!q.empty()){
            int u=q.front();q.pop();
            inq[u]=0;
            for(int i=0;i<G[u].size();i++){
                Edge& e=edges[G[u][i]];
                inq[u]=0;
                if(e.cap>e.flow&&d[e.to]>d[u]+e.cost){
                    d[e.to]=d[u]+e.cost;
                    p[e.to]=G[u][i];
                    a[e.to]=min(a[u],e.cap-e.flow);
                    if(!inq[e.to]) q.push(e.to),inq[e.to]=1;
                }
            }
        }
        if(d[t]==INF) return 0;
        flow+=a[t];
        cost+=d[t]*a[t];
        int u=t;
        while(u!=s){
            edges[p[u]].flow+=a[t];
            edges[p[u]^1].flow-=a[t];
            u=edges[p[u]].from;
        }
        return 1;
    }
    int Mincost(int s,int t)
    {
        int flow=0,cost=0;
        while(bellman_ford(s,t,flow,cost));
        return cost;
    }
};MCMF F;
int n,m;
int ti[30][30];

int main()
{
    freopen("in.txt","r",stdin);
    int T;cin>>T;
    while(T--){
        scanf("%d%d",&m,&n);
        REP(i,1,n){
            REP(j,1,m){
                scanf("%d",&ti[i][j]);
            }
        }
        F.init(n+m*n+2);
        int s=n+m*n+1,t=n+m*n+2;
        REP(i,1,m){
            REP(j,1,n){
                int v=i*n+j;
                REP(u,1,n){
                    F.addedge(u,v,1,j*ti[u][i]);
                }
                F.addedge(v,t,1,0);
            }
        }
        REP(i,1,n) F.addedge(s,i,1,0);
        printf("%d
",F.Mincost(s,t));
    }
    return 0;
}
View Code

没有AC不了的题,只有不努力的ACMER!
原文地址:https://www.cnblogs.com/--560/p/5173577.html