英文题意描述:

James has a grid plate of size N×N. And non-negative integers are written on each grid unit of the plate.
As James hates when there are too many numbers, he wants to cover a part of the plate with dominoes.
The size of a domino tile is 1×2. You can cover the numbers by putting the dominoes in a way that they overlap with exactly 2 grid units (horizontally or vertically).
However, a grid unit cannot be overlapped with several dominoes.
When you cover the grid plate with dominoes under this condition, your job is to minimize the sum of the numbers you can see.
 
[Input]
The first line contains a single integer Tㅡthe number of total test cases.
The first line of each test case contains the size of the grid plate, N(1 ≤ N ≤ 2000) and the number of dominoes, K(1 ≤ K ≤ 5).
The next N lines contain N integers that are greater than or equal to 0 and less than or equal to 1000. These integers mean the numbers written on the grid plate.
 
[Output]
Each line begins with ‘#x’(Test case number) followed by a space and then print the minimum value among the possible sums of numbers that are seen after covering the grid with dominoes.

Input Example
2 // Number of test case
3 1 // First test case, N=3, K=1
2 7 6 // Grid plate of size 3×3
9 5 1
4 3 8
4 2 // Second test case
1 2 4 0
4 0 5 4
0 3 5 1
1 0 4 1

Output Example
#1 31 // Answer to the first test case
#2 17

题意:N*N非负数字(最大1000)矩阵(最大边长2000),给1*2的多米诺骨牌(最多5个),求被多米诺骨牌遮挡之后的数字之和最小是多少。

思路:DFS,剪枝效仿贪心算法,只从前7 * (k - 1) + 1大的组合里寻找解决方案。

用domino去尽量大的覆盖掉原矩阵。直接暴力递归的话,层数太多了,且不说内存问题,时间上也不允许。但是可以知道,一些情况是不需要递归的。比如,矩阵最小的一个1*2区域。再怎么选也肯定轮不到选它。实际上肯定不是只有这一个最小的区域轮不到选它。

当这个节点小到,有7*(k-1)+1个值比它大的时候就轮不到它了。也就是说,实际上我们做递归时,只需要在7*(k-1)+1这么多个值中递归就行了。

举个例子,我们要选2个区域出来,选取第一个区域后,会有6个其他的1*2区域会和它重合,算上它自己,一个7个区域处于不可以选择的状态。假如这7个值,正好是最大的7个值。那么我们选第二个区域时,就只能选第8大的值。假如最大的7个值不都和第一个区域重合,那么我们就不需要第8个值。也就是说最坏的情况下。选2个区域,只需要在8个最大值中递归就行了。

 1 #include <stdio.h>
 2 typedef struct domino{
 3     int x1, x2, y1, y2, v;
 4     bool operator>(const domino &d){
 5         return this->v > d.v;
 6     }
 7 };
 8 domino d[50];
 9 int tc, n, k, dn, sub, sum;
10 int data[2001][2001];
11 bool b[2001][2001];
12 void push(int x1, int x2, int y1, int y2, int v){
13     d[dn] = { x1, x2, y1, y2, v };
14     for (int i = dn; i > 0; i--){
15         if (d[i] > d[i - 1]){
16             domino tmp = d[i];
17             d[i] = d[i - 1];
18             d[i - 1] = tmp;
19         }
20         else break;
21     }
22 }
23 void dfs(int deep, int loc, int tsum){
24     if (deep == k){
25         if (sub < tsum)sub = tsum;
26         return;
27     }
28     for (int i = loc; i < dn; i++){
29         if (!b[d[i].y1][d[i].x1] && !b[d[i].y2][d[i].x2]){
30             b[d[i].y1][d[i].x1] = b[d[i].y2][d[i].x2] = 1;
31             dfs(deep + 1, i + 1, tsum + d[i].v);
32             b[d[i].y1][d[i].x1] = b[d[i].y2][d[i].x2] = 0;
33         }
34     }
35 }
36 int main(){
37 //  freopen("sample_input.txt", "r", stdin);
38     scanf("%d", &tc);
39     for (int t = 1; t <= tc; t++){
40         scanf("%d%d", &n, &k);
41         sub = 0, sum = 0, dn = 7 * (k - 1) + 1;
42         for (int i = 0; i < dn; i++)d[i] = { 0, 0, 0, 0, 0 };
43         for (int i = 0; i < n; i++)
44         for (int j = 0; j < n; j++){
45             scanf("%d", &data[i][j]);
46             sum += data[i][j];
47         }
48         for (int i = 0; i < n; i++)
49         for (int j = 0; j < n; j++){
50             if (j + 1 < n)push(i, i, j, j + 1, data[i][j] + data[i][j + 1]);
51             if (i + 1 < n)push(i, i + 1, j, j, data[i][j] + data[i + 1][j]);
52         }
53         dfs(0, 0, 0);
54         printf("#%d %d\n", t, sum - sub);
55     }
56     return 0;
57 }

转载于:https://www.cnblogs.com/proscientist/p/8294901.html

练习题 James and Dominoes相关推荐

  1. 【SQL数据库】查询语句练习题

    表结构和初始化数据 drop database if exists emps; create database emps; use emps;create table emp( EMPNO INT, ...

  2. sql语句练习题或面试题

    根据下面表的描述,创建DEPT和EMP表,并运行下列SQL,最终完成后面的练习 1.   部门表:DEPT No. 字段名称 类型 描述 1 DEPTNO BIGINT 部门编号,由两位数字所组成(主 ...

  3. Oracle数据库练习题(1)

    一.建表 create table empgj(empno number(4,0) primary key,ename varchar2(10), job varchar2(9),mgr number ...

  4. 【天梯赛练习题(c语言)】

    天梯赛练习题(c语言) 1.L1-007 念数字 (10 分) 输入一个整数,输出每个数字对应的拼音.当整数为负数时,先输出fu字.十个数字对应的拼音如下: 0: ling 1: yi 2: er 3 ...

  5. 图论练习题(存起来练)

    =============================以下是最小生成树+并查集======================================  [HDU]  1213 How Man ...

  6. Unix Shell范例精解---grep和sed练习题

    题目来自Unix Shell范例精解这本书中的第四章和第五章,用的都是datebook这个文件,文件内容如下: Steve Blenheim:238-923-7366:95 Latham Lane, ...

  7. 2016计算机二级java_2016计算机二级JAVA练习题及答案

    2016计算机二级JAVA练习题及答案 21.下列选项中,不能输出100个整数的.是( ). A.for(int i=0;i<100;i++) System.out.println(i); B. ...

  8. C语言语句单选题,C语言练习题

    C语言练习题 C一个switch语句总是可以被一系列ifelse语句替换 D switch语句的测试表达式可以是任何类型 E当执行break语句时程序将停止执行 20在C语言中,在int num[5] ...

  9. word2003计算机应用考试,2017职称计算机考试Word2003操作练习题

    2017职称计算机考试Word2003操作练习题 实验操作能力是计算机考试考查的一项基本能力,下面是小编给大家提供的职称计算机考试Word2003操作练习题,大家可以参考练习,更多习题练习请关注应届毕 ...

最新文章

  1. oracle 如何预估将要创建的索引的大小
  2. 怎样批量调整word 图片大小?
  3. 机器学习从零开始-常见算法手推pure python
  4. 一图胜千言,这本交互式线代教科书让你分分钟理解复杂概念,佐治亚理工出品...
  5. c#之Stringbuilder、String、Append
  6. typescript 方法后面加感叹号_typescript专题(四) 「泛型」
  7. maven插件开发(二)
  8. 使用nat123动态解析公网ip
  9. 梁宁《产品思维》之5同理心训练:产品要顺应用户潜意识
  10. 概率论排列公式和组合公式实质 压强 : 压力=ps=压强*面积; 万有引力公式:
  11. mysql union 慢_mysql查询慢的原因和解决方案
  12. vue用html方式路由守卫,vue-router 实现导航守卫(路由卫士)的实例代码
  13. 高手进阶!终极内存技术指南
  14. 文件十六进制编辑软件HxD Hex Editor的使用
  15. math_(函数数列)极限的含义误区和符号梳理/邻域去心邻域邻域半径
  16. YOLOv5桌面应用开发(上)——附源代码
  17. android 全局换字体,Android 全局替换字体
  18. 跳跳虎辅助免费体验版
  19. matlab的多变量dmc源程序,基于MATLAB多变量DMC算法的仿真技术研究
  20. Qt定制化安装包工具

热门文章

  1. python语言需要英语非常好吗-Python用不好英语水平不够?这里有官方中文文档你看不看...
  2. python系统-基于Python搭建Django后台管理系统
  3. python excel 自动化-Python控制Excel实现自动化办公
  4. python语言入门w-Python算法基础
  5. python表白程序-用Python做一个表白小姐姐的程序
  6. python画图代码星星-Python打印“菱形”星号代码方法
  7. python编程入门与案例详解pdf-Flutter技术入门与实战 PDF 清晰版
  8. python自学网站有哪些-分享干货:三个新手自学Python的网站!
  9. python3中文手册-Python3.4中文手册 chm版
  10. python基本语法-Python语法基础50题