题目描述

莫莉斯·乔是圣域里一个叱咤风云的人物,他凭借着自身超强的经济头脑,牢牢控制了圣域的石油市场。

圣域的地图可以看成是一个n*m的矩阵。每个整数坐标点(x , y)表示一座城市吗,两座城市间相邻的定义为:对于城市(Ax, Ay)和城市(Bx, By),满足 \((Ax-Bx)^2 + (Ay-By)^2=1\)

由于圣域的石油贸易总量很大,莫莉斯意识到不能让每笔石油订购单都从同一个油库里发货。为了提高效率,莫莉斯·乔决定在其中一些城市里建造油库,最终使得每一个城市X都满足下列条件之一:

1.该城市X内建有油库,

2.某城市Y内建有油库,且城市X与城市Y相邻。

与地球类似,圣域里不同城市间的地价可能也会有所不同,所以莫莉斯想让完成目标的总花费尽可能少。如果存在多组方案,为了方便管理,莫莉斯会选择建造较少的油库个数。

输入输出格式

输入格式:

第一行两个正整数n,m,表示矩阵的大小。

接下来一个n行m列的矩阵F,\(F[i][j]\) 表示在城市(i,j)建造油库的代价。

输出格式:

输出两个数,建造方案的油库个数和方案的总代价。

输入输出样例

输入样例#1:

3 3

6 5 4

1 2 3

7 8 9

输出样例#1:

3 6

说明

对于30%数据满足 \(n*m<=25\) ;

对于100%数据满足\(n*m<=50,F[i][j]<=100000\)


好像挺水的一道状压

然而我还是WA了一发

感觉自己DP水平是普及==

一看数据范围,显然状压

但是我们发现对该点有贡献的点是该点的上下左右四个点

所以我们就设\(f[i][j][k][0]\)表示在第i行的状态是j,第i-1行的状态是k的最小花费

\(f[i][j][k][1]\)表示的是在最小花费下的最小建筑数量

如果这一层,上一层和上上层的状态可以满足上一层的状态就转移

最后统计一下第n行的合法答案就好辣

#include<cstdio>
#include<cstring>
#include<algorithm>
const int M = 55 ;
const int N = 130 ;
const int INF = 1e9 ;
using namespace std ;
inline int read() {
char c = getchar() ; int x = 0 , w = 1 ;
while(c>'9'||c<'0') { if(c=='-') w = -1 ; c = getchar() ; }
while(c>='0'&&c<='9') { x = x*10+c-'0' ; c = getchar() ; }
return x*w ;
} int n , m ;
int f[M][N][N][2] ;
// f[i][j][k] 第i-1行的状态是j,第i行的状态是k
int val[M][M] , MinC = INF , MinNum = INF ;
inline bool Istrue(int sit1 , int sit2 , int sit3) {
int sit = ((sit1|sit2)|sit3) ;
for(int i = 1 ; i <= m ; i ++) {
if(sit & (1<<(i - 1))) continue ;
if((sit2 & (1<<(i - 2)))|(sit2 & (1<<i))) continue ;
return false ;
}
return true ;
}
inline int query(int x , int sit , int &Num) {
int temp = 0 ;
for(int i = 1 ; i <= m ; i ++)
if(sit & (1<<(i - 1)))
temp += val[x][i] , ++ Num ;
return temp ;
}
int main() {
n = read() ; m = read() ;
for(int i = 1 ; i <= n ; i ++)
for(int j = 1 ; j <= m ; j ++)
val[i][j] = read() ;
for(int i = 0 ; i <= n ; i ++)
for(int j = 0 ; j < (1<<m) ; j ++)
for(int k = 0 ; k < (1<<m) ; k ++)
f[i][j][k][0] = f[i][j][k][1] = INF ;
int Num = 0 ;
for(int i = 0 ; i < (1<<m) ; i ++) {
Num = 0 ;
f[1][i][0][0] = query(1 , i , Num) ;
f[1][i][0][1] = Num ;
}
for(int i = 2 ; i <= n ; i ++) {
for(int j = 0 ; j < (1<<m) ; j ++) { // 本层
for(int k = 0 ; k < (1<<m) ; k ++) { // 上一层
for(int l = 0 ; l < (1<<m) ; l ++) { // 上上层
Num = 0 ;
if(!Istrue(j , k , l)) continue ;
int temp = f[i - 1][k][l][0] + query(i , j , Num) ;
if(f[i][j][k][0] > temp) {
f[i][j][k][0] = temp ;
f[i][j][k][1] = f[i - 1][k][l][1] + Num ;
}
else if(f[i][j][k][0] == temp && f[i][j][k][1] > f[i - 1][k][l][1] + Num)
f[i][j][k][1] = f[i - 1][k][l][1] + Num ;
}
}
}
}
for(int i = 0 ; i < (1<<m) ; i ++)
for(int j = 0 ; j < (1<<m) ; j ++) {
if(!Istrue(j , i , 0)) continue ;
if(f[n][i][j][0] < MinC) {
MinC = f[n][i][j][0] ;
MinNum = f[n][i][j][1] ;
}
else if(f[n][i][j][0] == MinC && f[n][i][j][1] < MinNum)
MinNum = f[n][i][j][1] ;
}
printf("%d %d\n",MinNum , MinC) ;
return 0 ;
}

[GDOI2014]拯救莫莉斯的更多相关文章

  1. [GDOI2014]拯救莫莉斯 状压DP

    题面: 莫莉斯·乔是圣域里一个叱咤风云的人物,他凭借着自身超强的经济头脑,牢牢控制了圣域的石油市场. 圣域的地图可以看成是一个n*m的矩阵.每个整数坐标点(x , y)表示一座城市( 1\le x\l ...

  2. 【[GDOI2014]拯救莫莉斯】

    可能我的状态比较鬼畜,应该没有人这么写 设\(dp[i][j][k]\)表示在第\(i\)行,放置油库的状态为\(j\),实际上周围已经有油库或者本身有油库的状态为\(k\)的时候的最小花费 由于我们 ...

  3. 拯救莫莉斯[GDOI2014]

    时间限制:1s     内存限制:256MB 问题描述 莫莉斯·乔是圣域里一个叱咤风云的人物,他凭借着自身超强的经济头脑,牢牢控制了圣域的石油市场. 圣域的地图可以看成是一个n*m的矩阵.每个整数坐标 ...

  4. 拯救莫莉斯 状压dp

    题目大意:每个点有费用,要求选出花费最少的一些点,使得全部点都满足:他被选或与他相邻的任意点被选. 没看清数据范围233333 和翻格子游戏一样,考虑上中下三行,可行才能转移 f[i][j][k]表示 ...

  5. [ GDOI 2014 ] 拯救莫莉斯

    \(\\\) \(Description\) 有一个 \(N\times M\) 的网格,每个格点都有权值,图是四连通的. 现在选择一个点集,使得每个格点要么被选中,要么连通的点之一被选中. 求这个点 ...

  6. luogu3888 GDOI2014拯救莫里斯 (状压dp)

    题目描述 莫莉斯·乔是圣域里一个叱咤风云的人物,他凭借着自身超强的经济头脑,牢牢控制了圣域的石油市场. 圣域的地图可以看成是一个n*m的矩阵.每个整数坐标点(x , y)表示一座城市\(( 1\le ...

  7. 暑假集训D13总结

    考试 又炸掉了= = 本来看着题就一脸茫然,默默的打暴力骗分,然后就交了卷= = 重要的是,在本机跑的毫无障碍的T3程序竟然在评测机CE啊喂,35分就没了啊喂(这可是比我现在分还高= =) 内心几近崩 ...

  8. words2

    餐具:coffee pot 咖啡壶coffee cup 咖啡杯paper towel 纸巾napkin 餐巾table cloth 桌布tea -pot 茶壶tea set 茶具tea tray 茶盘 ...

  9. python爬虫爬取全球机场信息

    --2013年10月10日23:54:43 今天需要获取机场信息,发现一个网站有数据,用爬虫趴下来了所有数据: 目标网址:http://www.feeyo.com/airport_code.asp?p ...

随机推荐

  1. c/c++ 位域的概念

    位域 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C语言又提供了一种数 ...

  2. 2017年12月14日 一个Java开发的Python之路----------------(二)

    说一个收获最大的,就是这个关闭流对象 之前写java读取文件的时候,最后往往要关闭流对象,以前我一直不明白,为什么,我不使用.close()方法,文件也可以读取成功,总感觉没有什么意义 原来是因为,这 ...

  3. 51nod - 1278 相离的圆 (二分)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1278 因为圆心都在x轴上,把每个圆转化成线段后,按线段的起点排序,那么对 ...

  4. Linux下Apache服务部署静态网站------网站服务程序

    文章链接(我的CSDN博客): Linux下Apache服务部署静态网站------网站服务程序

  5. hdu1025 Constructing Roads In JGShining&#39;s Kingdom(二分+dp)

    转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1025 Problem ...

  6. Growth: 一个关于怎样成为优秀Web Developer 的 App

    想了想还是决定在今天公布一个预览版.这样才干持续改进.Growth是一个关于怎样成为优秀的Web Developer的APP--结合技能树.成长路线图.进阶书单.Web七日谈以及一些小測验. 它是我对 ...

  7. C++进阶之虚函数表

    C++通过继承(inheritance)和虚函数(virtual function)来实现多态性.所谓多态,简单地说就是,将基类的指针或引用绑定到子类的实例,然后通过基类的指针或引用调用实际子类的成员 ...

  8. 开发人员调试工具Chrome Workspace

    Workspace是个什么样的东西呢?他可以在开发人员工具中调试改动js或者css同一时候自己主动保存文件.可以避免开发人员在工具中调试好,再到编辑器中改动一次代码的反复操作,可以提高一定的效率 配置 ...

  9. PAT Rational Arithmetic (20)

    题目描写叙述 For two rational numbers, your task is to implement the basic arithmetics, that is, to calcul ...

  10. uva 10452 Marcus

    Problem I Marcus, help! Input: standard input Output: standard output Time Limit: 2 Seconds "Fi ...