bzoj2547: [Ctsc2002]玩具兵

划了一天水,其实我还是有点愧疚的。

传送门

其实是水题,然而我真是太蠢了。。。

首先不考虑天兵,其他兵要到一个点去一定是通过它-另一种兵-它……这样多次交换的,并且交换对象是无所谓的,和它换的兵最终会是在原位置。

而且骑兵和步兵的数量相等,就不存在一个兵找不到人跟它换的情况,那么一个确定的方案下换的次数最多的兵换的次数就是答案。

先spfa找出每个兵到每个位置的最小换的次数,然后二分答案,把每个兵向它可以到的地方连边,跑最大匹配,考虑到还有天兵,而天兵是可以一步登天的超神存在,所以如果最大匹配数+现在check的ans>=总兵数即OK。

因为一直在划水,断断续续地写这个代码 ,又困得要命,仿佛活在梦中,结果竟然1A了,神奇。

//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
const int N=107;
typedef long long LL;
using namespace std;
int n,m,k,t,R[N],h[N][N],dis[N][N],dp[N][N][2],vis[N][N][2];
int dx[5]={0,0,1,-1},dy[5]={1,-1,0,0};

template<typename T>void read(T &x)  {
    char ch=getchar(); x=0; T f=1;
    while(ch!=‘-‘&&(ch<‘0‘||ch>‘9‘)) ch=getchar();
    if(ch==‘-‘) f=-1,ch=getchar();
    for(;ch>=‘0‘&&ch<=‘9‘;ch=getchar()) x=x*10+ch-‘0‘; x*=f;
}

struct node    {
    int x,y,o;
    node(){}
    node(int x,int y,int o):x(x),y(y),o(o){}
}b[N],p[N];

queue<node>que;
void spfa(int sx,int sy,int k) {
    memset(dp,127,sizeof(dp));
    if(k) dp[sx][sy][0]=0,que.push(node(sx,sy,0));
    else dp[sx][sy][1]=0,que.push(node(sx,sy,1));
    while(!que.empty()) {
        node now=que.front();
        que.pop();
        int x=now.x,y=now.y,o=now.o;
        vis[x][y][o]=0;
        for(int i=0;i<4;i++) {
            int xx=now.x+dx[i],yy=now.y+dy[i],oo,t;
            if(xx>=1&&xx<=n&&yy>=1&&yy<=m) {
                if((o==0&&h[xx][yy]>=h[x][y])||(o==1&&h[xx][yy]<=h[x][y])) t=dp[x][y][o],oo=o;
                else t=dp[x][y][o]+1,oo=o^1;
                if(dp[xx][yy][oo]>t) {
                    dp[xx][yy][oo]=t;
                    if(!vis[xx][yy][oo]) {
                        que.push(node(xx,yy,oo));
                        vis[xx][yy][oo]=1;
                    }
                }
            }
        }
    }
}

int ok[N][N],vs[N],pr[N],sum[N];
int find(int x) {
    for(int i=1;i<=2*k;i++) if(ok[x][i]&&!vs[i]) {
        vs[i]=1;
        if(!pr[i]||find(pr[i])) {
            pr[i]=x;
            return 1;
        }
    }
    return 0;
}

int ck(int ans) {
     int res=0;
     for(int i=1;i<=2*k;i++)
         for(int j=1;j<=t;j++) {
            if(dis[i][j]<=ans)
                for(int kk=1;kk<=R[j];kk++)
                    ok[i][sum[j-1]+kk]=1;
            else for(int kk=1;kk<=R[j];kk++)
                ok[i][sum[j-1]+kk]=0;
        }
    memset(pr,0,sizeof(pr));
    for(int i=1;i<=2*k;i++) {
        memset(vs,0,sizeof(vs));
        if(find(i)) res++;
    }
    if(res+ans>=2*k) return 1;
    else return 0;
}

int main() {
    read(n); read(m); read(k); read(t);
    for(int i=1;i<=2*k+1;i++) {
        read(b[i].x);
        read(b[i].y);
    }
    for(int i=1;i<=t;i++) {
        read(p[i].x);
        read(p[i].y);
        read(R[i]); sum[i]=sum[i-1]+R[i];
    }
    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) read(h[i][j]);
    memset(dis,127,sizeof(dis));
    for(int i=1;i<=2*k;i++) {
        spfa(b[i].x,b[i].y,(i<=k));
        for(int j=1;j<=t;j++)
            dis[i][j]=min(dp[p[j].x][p[j].y][0],dp[p[j].x][p[j].y][1]);
    }
    if(ck(0)) {
        puts("0"); return 0;
    }
    int l=1,r=1e9,ans=r;
    while(l<=r) {
        int mid=((l+r)>>1);
        if(ck(mid)) ans=mid,r=mid-1;
        else l=mid+1;
    }
    printf("%d\n",ans);
    return 0;
}
/*
4 6 2 5
1 1   1 5   4 1   4 5    3 3
1 2 1   2 6 1   3 2 1   3 6 1   4 3 1
3 2 6 1 3 5
2 1 7 4 4 6
2 3 1 4 3 4
4 3 4 3 2 3
*/

原文地址:https://www.cnblogs.com/Achenchen/p/8414201.html

时间: 2024-10-18 21:14:24

bzoj2547: [Ctsc2002]玩具兵的相关文章

[Bzoj 2547] [Ctsc2002] 玩具兵

2547: [Ctsc2002]玩具兵 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 317  Solved: 152[Submit][Status][Discuss] Description 小明的爸爸给他买了一盒玩具兵,其中有 K个步兵,K个骑兵和一个天兵,个个高大威猛,形象逼真.盒子里还有一个M*N棋盘,每个格子(i,j)都有一个高度Hij,并且大得足以容纳所有的玩具兵.小明把所有的玩具兵都放到棋盘上去,突然想到了一种很有趣的玩法:任意挑选

DNF NPK包名对照一览表

文章转载自:http://bbs.exrpg.com/thread-107917-1-1.html ┌ sprite.NPK                                                  登陆界面├ sprite_character.NPK                                        默认角色头像和角色轮廓├ sprite_character_common.NPK                               

&lt;老友记&gt;学习笔记

这是六个人的故事,从不服输而又有强烈控制欲的monica,未经世事的千金大小姐rachel,正直又专情的ross,幽默风趣的chandle,古怪迷人的phoebe,花心天真的joey——六个好友之间的情路坎坷,事业成败和生活中的喜怒哀乐,无时无刻不牵动着彼此的心,而正是正平凡的点点滴滴,却成为最令人感动与留恋的东西. 人物:1.瑞秋•格林(RACHEL GREENE)由珍妮佛•安妮斯顿(Jennifer Aniston)扮演 瑞秋是莫妮卡的高中同学,在与牙医未婚夫的婚礼上脱逃至莫妮卡处. 2.罗

《写在开始之前》

2016年9月,我的双学位学习开始了. 在同龄人之中我大概算是比较早接触PC的吧,在幼儿园时也就是9几年的时候家里就买了PC,那时候的PC还是windows 95,巨大的显示器占了快三分之一个桌子.那时候妈妈还在世,家里环境稍微好些,所以妈妈对电脑学习还是比较重视的.我学习电脑基本操作基本是靠自己折腾,尤其好笑的是我那时候认为在菜单里选了关机后,还需要再按一下电源键(其它电器带来的惯性思维,后来电脑烧坏了应该不是我的错吧哈哈),这样关机了几次才发现其实不需要--那时候连桌上弹珠都没有,只有红心大

lakka

这些标准列表文件名如下(暂时只给出常见主机的,太过稀奇的估计大家也不好找ROM)以下按机种英文名排序: Atari - 2600.lpl --- 雅达利2600家用游戏机Atari - 5200.lpl --- 雅达利5200家用游戏机Atari - 7800.lpl --- 雅达利7800家用游戏机Atari - Jaguar.lpl --- 雅达利美洲豹家用游戏机 Bandai - WonderSwan Color.lpl --- 万代天鹅彩色版Bandai - WonderSwan.lpl

hdu 1166:敌兵布阵(树状数组,练习题)

敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 37773    Accepted Submission(s): 15923 Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就

bzoj 1010 玩具装箱toy -斜率优化

P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具,第i件玩具经过压缩后变成一维长度为Ci.为了方便整理,P教授要求在一个一维容器中的玩具编号是连续的.同时如果一个一维容器中有多个玩具,那么两件玩具之间要加入一个单位长度的填充物,形式地说如果将第i件玩具到第j个玩具放到一个容器中,那么容器的长度将为 x=j-i+Sigma(Ck) i<=K<=j 制作容器的

BZOJ 1010: [HNOI2008]玩具装箱toy [DP 斜率优化]

1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 9812  Solved: 3978[Submit][Status][Discuss] Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具,第i件玩具经过压缩后变成一维长度为Ci.为了方便整理,P

动态规划(斜率优化):BZOJ 1010 【HNOI2008】 玩具装箱

玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 8218  Solved: 3233[Submit] Description P 教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维 容器中.P教授有编号为1...N的N件玩具,第i件玩具经过压缩后变成一维长度为Ci.为了方便整理,P教授要求在一个一维容器中的玩具编号是连续的. 同时如果一个一维