[JZOJ6299] 2019.08.12【NOIP提高组A】工厂
题目
题目大意
工厂内每个人只会操作一些机器。
他们会以随机的顺序来,每次选任意一台机器来操作。
一台机器只能由一个工人来操作。
可以花费一的代价来使某个工人学会一种机器。
问花费最少的代价,使得在所有的情况下每个人都能操纵一台机器。
正解
这题可以转化成个二分图。而答案一定满足:所有联通块都是个完全二分图。
我们要用最少的代价来造出这样的二分图。
预处理出所有的联通块,每个联通块用\((x,y)\)表示,意味着左边有\(x\)个,右边有\(y\)个。
于是就有了下面这个状压DP:\(f_{S,i}\)表示\(S\)集中的联通块都被使用了,其中完成了的联通块的\(x\)之和为\(i\)的最小边数。
等等,这个状态会不会存不下?
实际上,对于相同的\((x,y)\),我们只关心数量,所以可以进一步压缩。然后状态的数量就变得少了很多。
最后的答案记得要减去原来就有的边数。
代码
using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 33
inline void update(int &x,int y){x>y?x=y:0;}
int n;
char can[N][N];
bool vis[N][2];
int cntl,cntr,have;
void find(int x,bool k){
vis[x][k]=1;
if (k==0){
cntl++;
for (int i=1;i<=n;++i)
if (can[x][i]=='1' && !vis[i][1])
find(i,1);
}
else{
cntr++;
for (int i=1;i<=n;++i)
if (can[i][x]=='1' && !vis[i][0])
find(i,0);
}
}
int sc[N][N];
struct State{
int x,y;
int num;
} lis[N];
int m;
int pro[N];
int chose[N];
int f[200000][N];
void dfs(int k,int s,int x,int y){
if (k>m){
if (s==0)
f[0][0]=0;
for (int j=0;j<n;++j){
if (x==y)
update(f[s][x],f[s][j]+(x-j)*(x-j));
for (int i=1;i<=m;++i)
if (chose[i]<lis[i].num)
update(f[s+pro[i-1]][j],f[s][j]);
}
return;
}
for (int i=0;i<=lis[k].num;++i){
chose[k]=i;
dfs(k+1,s+i*pro[k-1],x+i*lis[k].x,y+i*lis[k].y);
}
}
int main(){
freopen("factory.in","r",stdin);
freopen("factory.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;++i){
scanf("%s",can[i]+1);
for (int j=1;j<=n;++j)
if (can[i][j]=='1')
have++;
}
for (int i=1;i<=n;++i){
if (!vis[i][0]){
cntl=cntr=0;
find(i,0);
sc[cntl][cntr]++;
}
if (!vis[i][1]){
cntl=cntr=0;
find(i,1);
sc[cntl][cntr]++;
}
}
pro[0]=1;
for (int i=0;i<=n;++i)
for (int j=0;j<=n;++j)
if (sc[i][j]){
lis[++m]={i,j,sc[i][j]};
pro[m]=pro[m-1]*(sc[i][j]+1);
}
memset(f,127,sizeof f);
f[0][0]=0;
dfs(1,0,0,0);
printf("%d\n",f[pro[m]-1][n]-have);
return 0;
}
总结
居然还有如此鬼畜的DP……
[JZOJ6299] 2019.08.12【NOIP提高组A】工厂的更多相关文章
- 2018.12.08【NOIP提高组】模拟B组总结(未完成)
2018.12.08[NOIP提高组]模拟B组总结 diyiti 保留道路 进化序列 B diyiti Description 给定n 根直的木棍,要从中选出6 根木棍,满足:能用这6 根木棍拼出一个 ...
- 2017.08.08【NOIP提高组】模拟赛B组
Summary 今天的题目也不算很难,唯一一道没做出来的题目是以前做过的,太不应该了. Problem T1 油滴扩展 题目大意 给你一堆点,你准备要在这么多的点当中滴油.你可以自己安排顺序,每次滴油 ...
- 2018.12.30【NOIP提高组】模拟赛C组总结
2018.12.30[NOIP提高组]模拟赛C组总结 今天成功回归开始做比赛 感觉十分良(zhōng)好(chà). 统计数字(count.pas/c/cpp) 字符串的展开(expand.pas/c ...
- NOIP提高组2004 合并果子题解
NOIP提高组2004 合并果子题解 描述:在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每一次合并,多多可以把两堆果子合并到一起,消 ...
- [NOIP提高组2018]货币系统
[TOC] 题目名称:货币系统 来源:2018年NOIP提高组 链接 博客链接 CSDN 洛谷博客 洛谷题解 题目链接 LibreOJ(2951) 洛谷(P5020) 大视野在线评测(1425) 题目 ...
- NOIP提高组初赛难题总结
NOIP提高组初赛难题总结 注:笔者开始写本文章时noip初赛新题型还未公布,故会含有一些比较老的内容,敬请谅解. 约定: 若无特殊说明,本文中未知数均为整数 [表达式] 表示:在表达式成立时它的值为 ...
- 津津的储蓄计划 NOIp提高组2004
这个题目当年困扰了我许久,现在来反思一下 本文为博客园ShyButHandsome的原创作品,转载请注明出处 右边有目录,方便快速浏览 题目描述 津津的零花钱一直都是自己管理.每个月的月初妈妈给津津\ ...
- 计蒜客 NOIP 提高组模拟竞赛第一试 补记
计蒜客 NOIP 提高组模拟竞赛第一试 补记 A. 广场车神 题目大意: 一个\(n\times m(n,m\le2000)\)的网格,初始时位于左下角的\((1,1)\)处,终点在右上角的\((n, ...
- 1043 方格取数 2000 noip 提高组
1043 方格取数 2000 noip 提高组 题目描述 Description 设有N*N的方格图(N<=10,我们将其中的某些方格中填入正整数,而其他的方格中则放入数字0.如下图所示(见样 ...
随机推荐
- dubbo源码学习(四):暴露服务的过程
dubbo采用的nio异步的通信,通信协议默认为 netty,当然也可以选择 mina,grizzy.在服务端(provider)在启动时主要是开启netty监听,在zookeeper上注册服务节点, ...
- linux常用命令 满足99%的开发需要
1.# 表示权限用户(如:root),$ 表示普通用户开机提示:Login:输入用户名password:输入口令 用户是系统注册用户成功登陆后,可以进入相应的用户环境.退出当前shell,输入:exi ...
- 制作一个自己的xhprof测试平台
1 1.首先安装php开发环境,比如lnmp. 2.安装xhprof ps: 记住从github上面下载(https://github.com/phacility/xhprof), 不要从pecl.p ...
- Linux/CentOS 7 timezone 修改
1.su - 登录root用户 2.timedatectl set-timezone {timezone} (set后面加想要设置的时区) 举例:timedatectl set-timezone As ...
- 6358. 【NOIP2019模拟2019.9.15】小ω的仙人掌
题目 题目大意 给你一串二元组\((a_i,b_i)\)的数列. 求最小的区间\([l,r]\)长度,满足\([l,r]\)中的每个二元组选或不选,使得\(\sum a_i=w\)且\(\sum b_ ...
- delphi xe10 手机内部系统相关操作(手机信息、震动、剪贴板、键盘、电话、拨号)
//获取手机信息 function GetPhoneInfo(): string; Var TelephonyManager: JTelephonyManager; TelephonyServiceN ...
- thinkphp 数据缓存
在ThinkPHP中进行缓存操作,一般情况下并不需要直接操作缓存类,因为系统内置对缓存操作进行了封装,直接采用S方法即可,例如: 缓存初始化 // 缓存初始化 S(array('type'=>' ...
- QueryList getData()方法中多次调用来实现递归多级采集。
<?php require 'QueryList/vendor/autoload.php'; use QL\QueryList; //获取每个li里面的h3标签内容,和class为item的元素 ...
- 经典单调栈最大子矩形——牛客多校第二场H
题目是求次大子矩形,那么在求最大子矩形的时候维护M1,M2即可 转移M2时比较的过程要注意一下 #include<bits/stdc++.h> using namespace std; # ...
- 创建用户的方法 3种mysql创建方法
mysql创建用户的方法分成三种:INSERT USER表的方法.CREATE USER的方法.GRANT的方法. 一.账号名称的构成方式 账号的组成方式:用户名+主机(所以可以出现重复的用户 ...