ZOJ 3578 Matrix
input:
第一行:N M C
后面C行:ai,bi,hi,xi,yi
problem:
一个N*M的网格平面,开始时平面上所有网格值为0
定义操作T(ai,bi,hi,xi,yi):
1.挑选出网格矩阵[xi,yi,xi+ai,yi+bi]中的最大值max
2.将网格矩阵[xi,yi,xi+ai,yi+bi]中的所有值赋为max+hi
求C次操作后,网格矩阵N*M中的最大值
数据范围
N<=1000,C<1000
ai,bi,hi,xi,yi(0<=hi<=10000,0<=xi<n,0<=yi<m)
解题:
看了网上的解法,类似于俄罗斯方块
暴力的做法,即对于个方块,遍历其前面的方块最多能跌倒的高度,dp方程为:
dp[i]=max(dp[j]+h[i]) 其中j<i且方块i与j相交
太久没做题了,这么简单的题也做不来了~~~~(>_<)~~~~
1 /**
2 ZOJ 3578 Matrix
3 input:
4 第一行:N M C
5 后面C行:ai,bi,hi,xi,yi
6
7 problem:
8 一个N*M的网格平面,开始时平面上所有网格值为0
9 定义操作T(ai,bi,hi,xi,yi):
10 1.挑选出网格矩阵[xi,yi,xi+ai,yi+bi]中的最大值max
11 2.将网格矩阵[xi,yi,xi+ai,yi+bi]中的所有值赋为max+hi
12 求C次操作后,网格矩阵N*M中的最大值
13
14 数据范围
15 N<=1000,C<1000
16 ai,bi,hi,xi,yi(0<=hi<=10000,0<=xi<n,0<=yi<m)
17
18 解题:
19 看了网上的解法,类似于俄罗斯方块
20 暴力的做法,即对于个方块,遍历其前面的方块最多能跌倒的高度,dp方程为:
21 dp[i]=max(dp[j]+h[i]) 其中j<i且方块i与j相交
22 太久没做题了,这么简单的题也做不来了~~~~(>_<)~~~~
23
24 */
25
26 #include<stdio.h>
27 #include<string.h>
28 const int N = 1000+10;
29 class Matrix {
30 public:
31 int left,right;
32 int up,down;
33 int height;
34 };
35
36 Matrix matrix[N];
37 int height[N];
38 inline bool isConnect(int x,int y) {
39 if(matrix[x].up<=matrix[y].down||matrix[x].right <= matrix[y].left)return false;
40 if(matrix[x].down >= matrix[y].up||matrix[x].left >= matrix[y].right) return false;
41 return true;
42 }
43 int main()
44 {
45 int n,m,c;
46 while(scanf("%d%d%d",&n,&m,&c)!=EOF)
47 {
48 int a,b,h,x,y;
49 for(int i=0;i<c;i++){
50 scanf("%d%d%d%d%d",&a,&b,&h,&x,&y);
51 matrix[i].left = x;
52 matrix[i].down = y;
53 matrix[i].right = (x + a)<n? (x+a):n;
54 matrix[i].up = (y + b)<m?(y + b):m;
55 matrix[i].height = h;
56 height[i] = 0;
57 }
58
59 for(int i=0;i<c;i++) {
60 for(int j=i+1;j<c;j++) {
61 if(isConnect(i,j)) {
62 if(height[i]+matrix[i].height>height[j])
63 height[j] = height[i]+matrix[i].height;
64 }
65 }
66 }
67
68 int max = 0;
69 for(int i=0;i<c;i++) {
70 max = max>height[i]+matrix[i].height?max:height[i]+matrix[i].height;
71 }
72
73 printf("%d\n",max);
74 }
75 }