题目

题目大意

工厂内每个人只会操作一些机器。

他们会以随机的顺序来,每次选任意一台机器来操作。

一台机器只能由一个工人来操作。

可以花费一的代价来使某个工人学会一种机器。

问花费最少的代价,使得在所有的情况下每个人都能操纵一台机器。


正解

这题可以转化成个二分图。而答案一定满足:所有联通块都是个完全二分图。

我们要用最少的代价来造出这样的二分图。

预处理出所有的联通块,每个联通块用\((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】工厂的更多相关文章

  1. 2018.12.08【NOIP提高组】模拟B组总结(未完成)

    2018.12.08[NOIP提高组]模拟B组总结 diyiti 保留道路 进化序列 B diyiti Description 给定n 根直的木棍,要从中选出6 根木棍,满足:能用这6 根木棍拼出一个 ...

  2. 2017.08.08【NOIP提高组】模拟赛B组

    Summary 今天的题目也不算很难,唯一一道没做出来的题目是以前做过的,太不应该了. Problem T1 油滴扩展 题目大意 给你一堆点,你准备要在这么多的点当中滴油.你可以自己安排顺序,每次滴油 ...

  3. 2018.12.30【NOIP提高组】模拟赛C组总结

    2018.12.30[NOIP提高组]模拟赛C组总结 今天成功回归开始做比赛 感觉十分良(zhōng)好(chà). 统计数字(count.pas/c/cpp) 字符串的展开(expand.pas/c ...

  4. NOIP提高组2004 合并果子题解

    NOIP提高组2004 合并果子题解 描述:在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每一次合并,多多可以把两堆果子合并到一起,消 ...

  5. [NOIP提高组2018]货币系统

    [TOC] 题目名称:货币系统 来源:2018年NOIP提高组 链接 博客链接 CSDN 洛谷博客 洛谷题解 题目链接 LibreOJ(2951) 洛谷(P5020) 大视野在线评测(1425) 题目 ...

  6. NOIP提高组初赛难题总结

    NOIP提高组初赛难题总结 注:笔者开始写本文章时noip初赛新题型还未公布,故会含有一些比较老的内容,敬请谅解. 约定: 若无特殊说明,本文中未知数均为整数 [表达式] 表示:在表达式成立时它的值为 ...

  7. 津津的储蓄计划 NOIp提高组2004

    这个题目当年困扰了我许久,现在来反思一下 本文为博客园ShyButHandsome的原创作品,转载请注明出处 右边有目录,方便快速浏览 题目描述 津津的零花钱一直都是自己管理.每个月的月初妈妈给津津\ ...

  8. 计蒜客 NOIP 提高组模拟竞赛第一试 补记

    计蒜客 NOIP 提高组模拟竞赛第一试 补记 A. 广场车神 题目大意: 一个\(n\times m(n,m\le2000)\)的网格,初始时位于左下角的\((1,1)\)处,终点在右上角的\((n, ...

  9. 1043 方格取数 2000 noip 提高组

    1043 方格取数  2000 noip 提高组 题目描述 Description 设有N*N的方格图(N<=10,我们将其中的某些方格中填入正整数,而其他的方格中则放入数字0.如下图所示(见样 ...

随机推荐

  1. 在ubuntu16下安装virtualenv+virtualenvwrapper

    ubuntu16已经安装好了py2和py3(自带的) bigni@bigni-Latitude-E6230:~/python_file/Django_project$ python python py ...

  2. 如何在vue-cli 中适当的配置,来满足自己项目需求 ?

    1. 改变index.js 中端口号host host:'localhost' 改为 host: '0.0.0.0' 然后换成自己的ip 访问: 2. 在vue 中运行cnpm run start 中 ...

  3. Excel的线程 与 SynchronizationContext的实现

    COM组件的线程模型与Excel多线程的背景知识 COM组件的线程模型被称之为Apartment模型,COM对象初始化时其执行上下文(Execution Context),他要么和单个线程关联STA( ...

  4. Mac OS X终端的常用操作命令(UNIX指令)

    用了十多年windows,终于换了个高配Mac,俗话说 无论前端还是后端最终还是走向了linux,无论是换了多少台PC最终都会走向Mac.不学习命令行用什么Mac? 干就完了~ pwd 显示现在的文件 ...

  5. 微信小程序之模板消息推送

    最近在用sanic框架写微信小程序,其中写了一个微信消息推送,还挺有意思的,写了个小demo 具体见官方文档:https://developers.weixin.qq.com/miniprogram/ ...

  6. pandas-索引

    一.按列取.按索引/行取.按特定行取 import numpy as np from pandas import DataFrame import pandas as pd df=DataFrame( ...

  7. on windows in superset sql lab error "module object has no attribute sigalrm"

    改下  utils.py   文件 It works after doing the following change (sorry for the massed up alignment, prob ...

  8. leetcode-140-单词拆分②*

    题目描述: 第一次提交:超时 O(N**N) class Solution: def wordBreak(self, s: str, wordDict: List[str]) -> List[s ...

  9. Jmeter-【beanshell处理器】-获取时间

    一.通过操作变量

  10. 37 VTK中的坐标系系统

    0 引言 在利用PCL的交互功能解决尺寸关联几何的指定问题时,涉及到一些显示上的操作.目前的需求是:将投影到注释平面上的点云,以与屏幕平齐的方式,显示在屏幕正中,这样方便用户进行操作.但是,在运用se ...