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\n",G.isap(s,t,n*n+3)*2);
}

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\n",ans);
    return 0;
}

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≤300;
100% 1≤N≤1000000
1≤Wi≤300;
1≤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(‘\n‘); }
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;
}

原文地址:https://www.cnblogs.com/rrsb/p/9064105.html

时间: 2024-10-13 10:56:42

CXMS 胡策2的相关文章

弱省胡策系列简要题解

现在不是非常爽,感觉智商掉没了,就整理一下最近弱省胡策的题目吧. 其实题目质量还是很高的. 如果实在看不懂官方题解,说不定这里bb的能给您一些帮助呢? [弱省胡策]Round #0 A 20%数据,O(n4)傻逼dp. 40%数据,O(n3)傻逼dp. 100%数据,令f(x1,y1,x2,y2)表示从(x1,y1)走到(x2,y2)的路径条数.于是所有路径就是f(1,2,n?1,m)×f(2,1,n,m?1).然而两条路径可能在中间的某个点相交,我们找出最早的交点,并在这个交点互换两条路径的后

【弱校胡策】2016.4.14 (bzoj2164)最短路+状压DP+矩阵乘法+高斯消元+树链剖分+线段树+背包DP

cyyz&qhyz&lwyz&gryz弱校胡策 命题人:cyyz ws_fqk T3暴力写挫了 50+10+0滚粗辣! 奇妙的约会(appointment.cpp/c/pas) [问题描述] DQS和sxb在网上结识后成为了非常好的朋友,并且都有着惊人 的OI水平.在NOI2333的比赛中,两人均拿到了金牌,并保送进入 HU/PKU.于是两人决定在这喜大普奔的时刻进行面基. NOI2333参赛选手众多,所以安排了n个考点,DQS在1号考点, 而sxb在n号考点.由于是举办全国性赛事

校内胡策(唯一一个想出来的)

2 第一题 (third.cpp/c/pas) 题目描述 小 R 最近沉迷于一个叫做 Slay.one 的游戏. 在这个游戏中,每一局有若干人参加,最终会产生一个优胜者.优胜者会获得 一个成就点. 现在小 R 已经利用某种手段得知了每场游戏有哪些人参加.假设所有人最初成 就点都是 0 ,小 R 想要知道所有游戏结束之后成就点最多的人至少有多少成就点. 校内胡策(唯一一个想出来的) 原文地址:https://www.cnblogs.com/Lance1ot/p/9445468.html

山西胡策 #7

A. B. C. 题意:给出(i, j)之类的约束表示要j必须先i,问1尽量靠前.2尽量靠前.3尽量靠前以此类推的最优方案,或输出无解. #include <bits/stdc++.h> using namespace std; const int N=100005; int cnt, ihead[N], in[N], ans[N], tot, n, m; struct E { int next, to; }e[N]; void add(int x, int y) { e[++cnt]=(E)

山西胡策 #6

A. 题意:求去掉d物品后容量为e最大背包.每个物品有三种属性,权值.容量.数量. #include <bits/stdc++.h> using namespace std; const int V=1000, N=1005; void zop(int *d, int w, int v) { for(int i=V; i>=v; --i) d[i]=max(d[i], d[i-v]+w); } void cmp(int *d, int w, int v) { for(int i=v; i

STOI补番队胡策

#1 第一轮是我出的. 比赛情况: #1 NanoApe 300 (完美AK) #2 && #3 swm_sxt / ccz  200 A.candy 这道题就是个nim游戏, 我们知道当且仅当选出的各堆糖果的异或和为0时,先手必败. 这样问题转化为从N个数中选1一些数使得他们的异或和为0的方案数. 30%,O(2^N) DFS. 假如只有询问, 那么可以直接用类似01背包的dp解决. for i = 1 ~ 1024 dp(i, x) += dp(i-1, x^w_i); dp(i, x

【弱省胡策】Round #6 String 解题报告

感觉这个题好神啊. 首先我们只管 $a = b$ 的情况,那么我们自然就可以把这个串对 $a$ 取模,然后用 KMP 求出能弄出几个其他的 B 串. 具体就是把串先倍长,然后倒过来,然后求 $Next$ 数组,然后从 $2n$ 开始沿着 $Next[]$ 跳,直到跳到 $\le n$ 的时候停止,看哪些位置被跳到了,哪些位置就是合法的. 问题是现在 $a \neq b$ 怎么办..? 我猜啊,我们可以求出限制是 $a$ 的倍数时,哪些 B 串是合法的,再求出限制是 $b$ 的倍数是,哪些是合法的

【弱省胡策】Round #7 Rectangle 解题报告

orz PoPoQQQ 的神题. 我的想法是:给每一个高度都维护一个 $01$ 序列,大概就是维护一个 $Map[i][j]$ 的矩阵,然后 $Map[i][j]$ 表示第 $i$ 根柱子的高度是否 $\ge j$. 那么怎么维护 $Map[i][j]$ 呢..? 首先我们把柱子按照高度从小到大排序,然后依次给每个高度建主席树,初始时 $Map[i][0]$ 全是 $1$,然后如果当前高度 $i$ 比某个柱子 $j$ 的高度要大了,那么就单点修改 $Map[i][j]$,然后这个就是主席树动态开

【弱省胡策】Round #5 Handle 解题报告

这个题是我出的 sb 题. 首先,我们可以得到: $$A_i = \sum_{j=i}^{n}{j\choose i}(-1)^{i+j}B_j$$ 我们先假设是对的,然后我们把这个关系带进来,有: $$B_i = \sum_{j=i}^{n}{j\choose i}A_j = \sum_{j=1}^{n}{j\choose i}\sum_{k=j}^{n}{k\choose j}(-1)^{j+k}B_k = \sum_{j=i}^{n}B_j\sum_{k=i}^{j}{j\choose k