hdu4975 行列和构造矩阵(dp判断唯一性)
题意:
和hdu4888一样,只不过是数据加强了,就是给你行列的和,让你构造一个矩阵,然后判断矩阵是否唯一。
思路:
构造矩阵很简单,跑一次最大流就行了,关键是判断矩阵的唯一性,之前的那个4888我用的是深搜找环过的,这个题目就TLE了,数据加强了,对于判断矩阵的唯一性我们可以这么想假如某一行的i列和j列满足 i列的这个> 0 && j列的这个 < 9此时我们再在另一行找到 i列的这个< 9 && j列的这个 > 0就可以把>0 的拿出来一个放在<9的上面,这样答案就不唯一了,对于最大流跑完后的到的矩阵,如果我们暴力判断上面的哪些情况的话是大约O(n^4)这样就比DFS找环还浪费时间,所以我们要用到dp优化,dp[i][j]记录的是在当前的状态之前,是否存在在某一行中,i列<9,j列>0,这样我们就可以利用之前状态的结果来节省一层for(具体看代码),但是这样还是TLE了,我们在每个for前面加几个小优化就可以过了。
#include<stdio.h> #include<string.h> #include<queue>#define N_node 1005 #define N_edge 600000 #define INF 1000000000 using namespace std;typedef struct {int to ,next ,cost; }STAR;typedef struct {int t ,x; }DEP;STAR E[N_edge]; DEP xin ,tou; int list[N_node] ,listt[N_node] ,tot; int deep[N_node]; int row[505] ,col[505]; int map[505][505]; int dp[505][505];void add(int a ,int b ,int c) {E[++tot].to = b;E[tot].cost = c;E[tot].next = list[a];list[a] = tot;E[++tot].to = a;E[tot].cost = 0;E[tot].next = list[b];list[b] = tot; }bool BFS_Deep(int s ,int t ,int n) {memset(deep ,255 ,sizeof(deep));deep[s] = 0;xin.x = s ,xin.t = 0;queue<DEP>q;q.push(xin);while(!q.empty()){tou = q.front();q.pop();for(int k = list[tou.x] ;k ;k = E[k].next){xin.x = E[k].to;xin.t = tou.t + 1;if(deep[xin.x] != -1 || !E[k].cost)continue;deep[xin.x] = xin.t;q.push(xin);}}for(int i = 0 ;i <= n ;i ++)listt[i] = list[i];return deep[t] != -1; }int minn(int x ,int y) {return x < y ? x : y; }int DFS_Flow(int s ,int t ,int flow) {if(s == t) return flow;int nowflow = 0;for(int k = listt[s] ;k ;k = E[k].next){listt[s] = k;int to = E[k].to;int c = E[k].cost;if(deep[to] != deep[s] + 1 || !c)continue;int tmp = DFS_Flow(to ,t ,minn(c ,flow - nowflow));nowflow += tmp;E[k].cost -= tmp;E[k^1].cost += tmp;if(flow == nowflow)break; } if(!nowflow) deep[s] = 0;return nowflow; }int DINIC(int s ,int t ,int n) {int ans = 0;while(BFS_Deep(s ,t ,n)){ans += DFS_Flow(s ,t ,INF);}return ans; }bool jude(int n ,int m ,int mktot) {int i = 1 ,j = 1 ,k;for(k = mktot + 1 ;k <= tot ;k += 2){ map[i][j] = E[k].cost;if(++j > m) {i ++ ,j = 1;}} memset(dp ,0 ,sizeof(dp));for(i = 1 ;i <= n ;i ++){if(row[i] == 0 || m * 9 == row[i])continue;for(j = 1 ;j <= m ;j ++){if(col[j] == 0 || n * 9 == col[j])continue; for(k = j + 1 ;k <= m ;k ++){int mk1 = 0 ,mk2 = 0;if(map[i][j] < 9 && map[i][k] > 0){if(dp[k][j]) return 1;mk1 ++;}if(map[i][j] > 0 && map[i][k] < 9){if(dp[j][k]) return 1;mk2 ++;}if(mk1) dp[j][k] = 1;if(mk2) dp[k][j] = 1;}}}return 0; }int main () {int n ,m ,i ,j ,s1 ,s2 ,a ,mkk;int t ,cas = 1;scanf("%d" ,&t);while(t--){scanf("%d %d" ,&n ,&m);s1 = s2 = mkk = 0;memset(list ,0 ,sizeof(list)) ,tot = 1;for(i = 1 ;i <= n ;i ++){scanf("%d" ,&a);add(0 ,i ,a);s1 += a;if(m * 9 < a) mkk = 1;row[i] = a;}for(i = 1 ;i <= m ;i ++){scanf("%d" ,&a);add(i + n ,n + m + 1 ,a);s2 += a;col[i] = a;if(n * 9 < a) mkk = 1;}printf("Case #%d: " ,cas ++);if(s1 != s2 || mkk){puts("So naive!");continue;} int mktot = tot + 1; for(i = 1 ;i <= n ;i ++)for(j = 1 ;j <= m ;j ++)add(i ,j + n ,9);int maxflow = DINIC(0 ,n + m + 1 ,n + m + 1); if(s1 != maxflow){puts("So naive!");continue;} jude(n ,m ,mktot)? puts("So young!"):puts("So simple!");}return 0; }
hdu4975 行列和构造矩阵(dp判断唯一性)相关推荐
- POJ 2396 构造矩阵(上下流)
题意: 要求构造一个矩阵,给你行和,列和,还有一些点的上下范围,输出一个满足题意的矩阵. 思路: 这个题目很经典,这是自己看上下流后接触的第一道题,感觉很基础的一道题目,现在我 ...
- hdu4888 最大流(构造矩阵)
题意: 让你构造一个矩阵,满足每一行的和,和每一列的和都等于他给的,还要判断答案是否唯一,还有一点就是矩阵内所有的数字都是[0,k]范围的. 思路: 这个题目看完就让我想起了h ...
- hdu 1757 A Simple Math Problem 构造矩阵
题意:函数f(x), 若 x < 10 f(x) = x. 若 x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + -- + ...
- HDU-6470 Count (构造矩阵+矩阵快速幂)
题目链接 Problem Description Farmer John有n头奶牛. 某天奶牛想要数一数有多少头奶牛,以一种特殊的方式: 第一头奶牛为1号,第二头奶牛为2号,第三头奶牛之后,假如当前奶 ...
- BZOJ 3240 构造矩阵+矩阵快速幂
思路: ax+b cx+d 构造矩阵+矩阵快速幂 (需要加各种特判,,,,我好像加少了- ) //By SiriusRen #include <cstdio> #include <c ...
- PYTHON---下三角矩阵的判断
下三角矩阵判断 描述 下三角矩阵指主对角线以上的元素都为0的矩阵:主对角线为从矩阵的左上角至右下角的连线. 本题要求编写程序,判断一个给定的方阵是否下三角矩阵. 输入 输入第一行给出一个正整数T,为待 ...
- Matrix Power Series(矩阵快速幂,二分法/构造矩阵套矩阵)
传送门 题意: 思路: 方法一:(二分) 分析: 奇偶分类讨论: 1.代码: #include <iostream> #include <cstdio> #include &l ...
- 简单计数(构造矩阵 矩阵快速幂优化dp)
传送门 示例1 输入 1 1 输出 0 分析: 代码: #include <bits/stdc++.h>using namespace std; typedef long long ll; ...
- 动态规划: dp+递推——确定动态矩阵dp含义,确定每个状态下面临的选择和对结果值影响,选择符合题意的作为结果存储在dp中
1.动态规划:每一个状态一定是由之前的状态推导出来的,通过总结归纳发现递推关系 2.解决动态规划问题的步骤: 确定dp数组(dp table)以及下标的含义: 每个单元内 题目所求的值,一维.二维 确 ...
最新文章
- centos vim配置高亮语法和格式化粘贴
- 说了低调...这下百度知道了...
- 在python中等号前面与后面分别是什么意思-Python中冒号等于(:=)是什么意思?...
- Android.mk解析
- 快速启动栏的现实桌面快捷方式
- bim 模型web页面展示_BIM+装配式建筑工程师2020年必须拿下的技能证书
- 信用贷款额度是怎么确定的?
- mysql启动报错:Another MySQL daemon already running with the same unix socket.
- NAR丨方海发布免疫疾病遗传靶点数据库“优先指数”,助力计算转化医学研究...
- js 值类型和引用类型
- kali攻击手机_kali linux入侵安卓手机
- 电阻参数_电阻的基础知识和参数介绍
- JAVA如何在LINUX里编程,如何使用加多宝(jdb)在linux下调试Java程序
- c语言编程定位的计算机,高校计算机专业C语言教学的四个定位
- pc投屏android软件,Scrcpy安卓电脑投屏软件下载
- 梁权财到徐闻生态工业集聚区调研
- 多种方法进行去基线处理
- html编写邮件发送_如何编写HTML电子邮件通讯
- bat脚本中如何多次键盘输入并判断_第四章: Python脚本获取聚宽(JQData)免费行情数据...
- floorplan学习笔记