soj 2800 三角形(DP)
2015-10-28 16:22
288 查看
题意
给你一个大三角形,黑色的是被减去的,白色的是剩下的,问剩下的白色区域中,最大的倒三角形是?
分析:
看到这个题,首先想一下暴力,恩..可以搞,稳定超时.
然后我们需要去找如何DP了么…
那么是不是可以用直观的记忆化搜索呢?….想了一下,好像并不是很直观…
只有强行dp了么,找一找把当前的问题,分解为前面一个阶段的多个状态的子问题决定的.
那么我们定义以点(i,j)为顶点的倒三角形的最大面积为dp[i][j]吧,这可以分解么??
貌似可以分解为它上面左右两边的两个倒三角形来做啊…
这样取其上边两个倒三角形中较小的一个的面积的2倍,减去中间重叠的部分,加上多出的两个顶点即可,求出dp[i][j],有转移方程:dp[i][j]=min(dp[i−1][j−1],dp[i−1][j+1])+2−k;
其中k为中间的重叠部分,可有左右两边较小上交有的高减一的平方算出.(本题中高平方即为三角形面积).
但是感觉..这样写在好难看的样子,好吧也能ac就这样了吧……
给你一个大三角形,黑色的是被减去的,白色的是剩下的,问剩下的白色区域中,最大的倒三角形是?
分析:
看到这个题,首先想一下暴力,恩..可以搞,稳定超时.
然后我们需要去找如何DP了么…
那么是不是可以用直观的记忆化搜索呢?….想了一下,好像并不是很直观…
只有强行dp了么,找一找把当前的问题,分解为前面一个阶段的多个状态的子问题决定的.
那么我们定义以点(i,j)为顶点的倒三角形的最大面积为dp[i][j]吧,这可以分解么??
貌似可以分解为它上面左右两边的两个倒三角形来做啊…
这样取其上边两个倒三角形中较小的一个的面积的2倍,减去中间重叠的部分,加上多出的两个顶点即可,求出dp[i][j],有转移方程:dp[i][j]=min(dp[i−1][j−1],dp[i−1][j+1])+2−k;
其中k为中间的重叠部分,可有左右两边较小上交有的高减一的平方算出.(本题中高平方即为三角形面积).
但是感觉..这样写在好难看的样子,好吧也能ac就这样了吧……
#include <cstdio> #include <cstring> #include <cmath> #include <iostream> using namespace std; const int mod = 1e9 + 9, maxn = 2e3 +9, INF = 0x3fffffff; typedef long long ll; int n, dp[maxn][maxn]; char g[maxn][maxn]; #define max(x, y) (x) > (y) ? (x) : (y) #define min(x, y) (x) < (y) ? (x) : (y) int main(void) { while (true) { scanf("%d", &n); if (!n) break; for (int i = 0; i <= n + 1; i++) { for (int j = i - 1; j <= 2 * n - i + 1; j++) { g[i][j] = 'X'; } } for (int i = 1; i <= n; i++) { for (int j = i; j <= 2 * n - i; j++) { char c = getchar(); if (c != 'X' && c != 'O') { j--; continue; } g[i][j] = c; dp[i][j] = g[i][j] == 'O' && j % 2 == i % 2 ? 1 : 0; } } int ans = -INF; for (int i = 1; i <= n; i++) { for (int j = i; j <= 2 * n - i; j++) { ans = max(ans, dp[i][j]); if (g[i][j] != 'O') continue; if (j % 2 == i % 2) { if (g[i - 1][j] == 'O' && g[i - 1][j - 1] == 'O' && g[i - 1][j + 1] == 'O') { int k = min(dp[i - 1][j - 1], dp[i - 1][j + 1]); dp[i][j] = k * 2 + 2 - (int(sqrt(double(k)) + 0.4) - 1) * (int(sqrt(double(k)) + 0.4) - 1); } } ans = max(ans, dp[i][j]); } } printf("%d\n", ans); } return 0; }
相关文章推荐
- 实现FPGA Verilog HDL与NIOS II的通信数据交换——利用PIO实现通信
- Java中数据输入输出流
- 数据结构实验之二叉树的建立与遍历
- zcmu1654
- 排序刷题方法
- Ofbiz中的.groovy文件
- php网站开发与Ajax的实现
- 多进程编程
- 触发 select
- jquery 筛选元素 (3)
- 比特币交易构成(一)
- 在驱动中添加syfs系统接口
- whois原理
- Android Camera API2.0下全新的Camera FW/HAL架构简述
- java中的打印流
- app版本更新问题
- 初见——AutoMapper
- rails 使用bootstrap及bootswatch
- RT: TCP REUSEADDR or REUSEPORT
- HDU 5115 Dire Wolf(区间DP)