码迷,mamicode.com
首页 > 其他好文 > 详细

2015-11-3-Training(for 2014th)

时间:2015-11-03 22:45:20      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:

A:(hdu1081)

题意:

  求和最大的子矩阵

解决:

  先考虑一维数组,可以O(n)复杂度求出 和值最大的连续子序列。

  同理,对每一行维护前缀和,然后枚举从 l 列到 r 列,每行的 l 列到 r 列可以通过前缀和O(1)求出,然后对每行的 l 列和r 列之间的和值作为一维数组的元素,O(n)求出答案。

  总复杂度 :O(n3)

技术分享
 1 #include <bits/stdc++.h>
 2 
 3 const int MAXN = 133;
 4 
 5 int n;
 6 int ma[MAXN][MAXN];
 7 
 8 int main()
 9 {
10     while (~scanf("%d", &n)) {
11         for (int i = 1; i <= n; ++i) {
12             ma[i][0] = 0;
13             for (int j = 1; j <= n; ++j) {
14                 scanf("%d", &ma[i][j]);
15                 ma[i][j] += ma[i][j-1];
16             }
17         }
18         int res = -0x7fffffff;
19         for (int l = 1; l <= n; ++l) {
20             for (int r = l; r <= n; ++r) {
21                 int tmp = 0, ans = -0x7fffffff;
22                 for (int i = 1; i <= n; ++i) {
23                     int ele = ma[i][r] - ma[i][l-1];
24                     tmp += ele;
25                     ans = std::max(ans, tmp);
26                     if (tmp < 0) {
27                         tmp = 0;
28                     }
29                 }
30                 res = std::max(res, ans);
31             }
32         }
33         printf("%d\n", res);
34     }
35 }
View Code

 

B:(hdu1060)

题意:

  N^N的最左边一位数字

解决:

  A = lg(nn) = n * lg(n)

  则 10A = nn, 设p 为 A 的小数部分,则10p 的整数部分就是答案

 

C:(hdu1007)

题意:

  平面最近点对

解决:

  这个题目比较取巧,解法很多。

  可以用旋转卡壳,可以分治,也可以两次排序直接求

  有一点很重要的思想,如果两个点是平面最近点,则以这两个点为对角线的矩形中一定没有其他点。根据这个思想可以排序两次,用相邻点的距离维护最小值。

  复杂度:O(n*log(n))

 

D:(hdu4007)

题意:

  给定n个点,求边长为R的正方形最多可以框住多少点(可以在边框上)

解决:

  解法一:可以用扫描线,对每个点,以这个点为左下角点构造出一个矩形,则一共有1000个矩形,求个矩形面积交,线段树维护区间最大值即可。

  解法二:先对所有点按照横坐标排序,从左到右枚举点,作为矩形左边框的横坐标,二分出矩形框能框住的最右边的点。这些点的横坐标差值最大不超过R,将这些点的纵坐标放在一个数组里面,排序之后尺取法扫一遍。

  二者复杂度均为:O(n*log(n))

  

技术分享
 1 #include <bits/stdc++.h>
 2 
 3 struct Point{
 4     int x, y;
 5     bool operator < (const Point &tmp) const
 6     {
 7         return x < tmp.x;
 8     }
 9 }point[1000+10];
10 
11 
12 
13 int n, R;
14 int t[1000+10];
15 
16 int check(int l, int r)
17 {
18     int cnt = 0;
19     for (int i = l; i <= r; ++i)
20         t[++cnt] = point[i].y;
21     std::sort(t+1, t+1+cnt);
22     int i = 1, j = 1;
23     int res = 0;
24     int tmp = 0;
25     while (j <= cnt) {
26         if (t[j] - t[i] <= R) {
27             ++j;
28             ++tmp;
29         }
30         else {
31             ++i;
32             --tmp;
33         }
34         res = std::max(res, tmp);
35     }
36     return res;
37 }
38 
39 int main()
40 {
41     while (~scanf("%d%d", &n, &R)) {
42         for (int i = 1; i <= n; ++i)
43             scanf("%d%d", &point[i].x, &point[i].y);
44         std::sort(point+1, point+1+n);
45         int res = 0;
46         for (int i = 1; i <= n; ++i) {
47             int l = i, r = n;
48             while (l <= r) {
49                 int mid = l + r >> 1;
50                 if (point[mid].x > point[i].x + R)
51                     r = mid - 1;
52                 else
53                     l = mid + 1;
54             }
55             res = std::max(res, check(i ,l-1));
56         }
57         printf("%d\n", res);
58     }
59 }
View Code

 

E:(hdu1176)

题意:

  天上会有n个馅饼掉下来,分别是在t时刻,x位置(0 <= x <= 10),人一开始在5位置,每时刻可以左移或者右移一个单位,求能接到馅饼最大值

解决:

  cake[t][x]为在t时刻x位置会有多少馅饼掉下来。

  dp[t][x] = max(dp[t-1][x-1], dp[t-1][x], dp[t+1][x]) + cake[t][x];

 

2015-11-3-Training(for 2014th)

标签:

原文地址:http://www.cnblogs.com/takeoffyoung/p/4934559.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!