UVA - 10558 A Brief Gerrymander
来源:互联网 发布:ai mac版 编辑:程序博客网 时间:2024/05/01 00:47
题意:一个棋盘,横竖线都是从1到100标号(竖线从左到右标,横线从下到上标),输入n表示有n个被标记的格子,是给出这个格子的左下角坐标,然后输入m,在输入m个数,表示在这些竖线的地方切开棋盘(其实只切了m-2刀,因为2刀必须是1和100,相当于没有),然后输入A,表示你要在横上上切A刀(其实也只是A-2刀,因为2刀必须在横线的1和100)。那么就可以把棋盘很多个大小不一的方块(矩形),只要这些方块中有被标记的小格子(1个或多个),那么这个方块就是一个选区,我们是要使到选区的个数最多
思路: 有想着肯定是要枚举(i,j)行之间的最大值的,但是还是写不出来,看了题解,使用预处理[i,j]间的个数,然后就可以枚举啦 ,f[i][j]表示在前j行切i刀的最大值,并记录切的行数,因为第1,100 行是一定要切的,所以从第2刀开始枚举,j行从i+1开始就可以了,还有就是这道题具有最优子结构,就是第前j行切i刀的最大位置,一定是包含前p[i][j]行切i-1刀的结果,所以我们就得到打印结果的方式了
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAXN = 110;int N,S,A,g[MAXN][MAXN],f[MAXN][MAXN],street[MAXN];int t[MAXN][MAXN],st[MAXN][MAXN][MAXN],s[MAXN][MAXN],p[MAXN][MAXN];int init(){ int i,j,k,flag,x,y; scanf("%d",&N); if (N == -1) return 0; memset(g,0,sizeof(g)); for (i = 0; i < N; i++){ scanf("%d%d",&y,&x); g[x][y] = 1; } scanf("%d",&S); for (i = 0; i < S; i++) scanf("%d",&street[i]); scanf("%d",&A); memset(t,0,sizeof(t)); for (i = 2; i <= 100; i++) for (j = 1; j < S; j++){ flag = 0; for (k = street[j-1]; k < street[j]; k++) if (g[i-1][k]) //是左下角标记 flag = 1; if (flag) t[i][j] = 1; //前i行前j刀是否有标记的 } memset(s,0,sizeof(s)); memset(st,0,sizeof(st)); for (i = 1; i < 100; i ++) for (j = i + 1; j <= 100; j++){ for (k = 1; k < S; k++) st[i][j][k] |= st[i][j-1][k]; //确定在竖切的(i,j)区域的块数 for (k = 1; k < S; k++) // 确定j行加进去后有没有 st[i][j][k] |= t[j][k]; for (k = 1; k < S; k++) //确定有几个 if (st[i][j][k]) s[i][j]++; } return 1;}void print(int i,int k){ if (k != 1) print(i-1,p[i][k]); printf(" %d",k);}void solve(){ int i,j,k,max; memset(f,-1,sizeof(f)); for (i = 2; i <= 100; i++){ f[1][i] = s[1][i]; p[1][i] = 1; } for (i = 2; i < A; i++) for (j = i + 1; j <= 100; j++){ for (k = i; k < j; k++) if (f[i-1][k]+s[k][j] > f[i][j]){ f[i][j] = f[i-1][k] + s[k][j]; p[i][j] = k; } } printf("%d",A); print(A-1,100); printf("\n");}int main(){ while (init()) solve(); return 0;}
- UVA - 10558 A Brief Gerrymander
- uva 10558 - A Brief Gerrymander
- UVA - 10558 A Brief Gerrymander
- uva 10558 - A Brief Gerrymander(记忆化搜索)
- uva 10558 A Brief Gerrymander (dp记忆化搜索)
- UVA - 10558A Brief Gerrymander(递推)
- UVA - 10558 A Brief Gerrymander 很抽象的题目
- UVA10558- A Brief Gerrymander
- uva 10558 - A Brief Gerrymander (dp之不好理解的题意)
- A brief advice
- A brief on using CreateRemoteThread
- A Brief Introduction to IoC
- A Brief Introduction to IoC
- A Brief Introduction to REST
- A Brief Introduction to REST
- Analytical Functions: A Brief Introduction
- A Brief Introduction to OVF
- A Brief Introduction to Myself
- Oracle Data Integrator 介绍
- SRM 593 Div1 L1:HexagonalBoard,用染色法判断无向图是否为二分图
- Red hat AS oracle11g 手工创建OEM
- 软件架构师需要掌握哪些知识?
- 最长字符串匹配算法(KMP算法)
- UVA - 10558 A Brief Gerrymander
- 鼠标放上去显示全部文字,不放上去,显示部分文字jquery效果,包括隐藏部分文字
- 怎样找到sql报错的存储过程和触发器及语句
- 设计jquery插件
- STL vector常用的几个成员的用法
- 2 synchronized 和 Lock+Condtion 对比
- 28岁的我站在人生十字路口该怎么走?
- CODE 77: Merge Intervals
- Windows下搭建Eclipse4.3+Android4.0开发环境!