POJ 3034 Whac-a-Mole(三維dp+處理小技巧)
題目感覺不錯,以後還得再做做。
題意:打地鼠,n*n的棋盤,每秒特定的格子上會有地鼠出沒。給一個錘子,比如錘子前一次在(x1, y1),現在移動到
(x2, y2)。則它可以打掉(x1, y1) -> (x2, y2)連線上的所有地鼠。錘子每次最多移動的距離為d。求最後最多能打到
多少個地鼠。
主要的思路就是用該點求出與該點相鄰的點的狀態。
dp[t][x][y]表示時間為t是,錘子在(x, y)座標的最大值。列舉x,y,求t + 1時間到(xx, yy)的最優值, dis(x, y, xx,
yy) <= d。在計算(x, y) -> (xx, yy)的時候不能一個單位一個單位的加,否則會超時。dx表示x -> xx的偏移量,
dy表示y -> yy的偏移量。
處理小技巧:求出dx, dy的最大公約數tp。 dx /= tp, dy /= tp。這樣從(x, y) 到(xx, yy)時沒次x
+= dx, y += dy;
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 3179 | Accepted: 961 |
Description
While visiting a traveling fun fair you suddenly have an urge to break the high score in the Whac-a-Mole game. The goal of the Whac-a-Mole game is to… well… whack moles. With a hammer. To make the job easier you have first consulted the fortune teller and now you know the exact appearance patterns of the moles.
The moles appear out of holes occupying the n2 integer points (x, y) satisfying 0 ≤ x, y < n in a two-dimensional coordinate system. At each time step, some moles will appear and then disappear again before the next time step. After the moles appear but before they disappear, you are able to move your hammer in a straight line to any position (x2, y2) that is at distance at most d from your current position (x1, y1). For simplicity, we assume that you can only move your hammer to a point having integer coordinates. A mole is whacked if the center of the hole it appears out of is located on the line between (x1, y1) and (x2, y2) (including the two endpoints). Every mole whacked earns you a point. When the game starts, before the first time step, you are able to place your hammer anywhere you see fit.
Input
The input consists of several test cases. Each test case starts with a line containing three integers n, d and m, where n and d are as described above, and m is the total number of moles that will appear (1 ≤ n ≤ 20, 1 ≤ d ≤ 5, and 1 ≤ m ≤ 1000). Then follow m lines, each containing three integers x, y and t giving the position and time of the appearance of a mole (0 ≤ x, y < n and 1 ≤ t ≤ 10). No two moles will appear at the same place at the same time.
The input is ended with a test case where n = d = m = 0. This case should not be processed.
Output
For each test case output a single line containing a single integer, the maximum possible score achievable.
Sample Input
4 2 6 0 0 1 3 1 3 0 1 2 0 2 2 1 0 2 2 0 2 5 4 3 0 0 1 1 2 1 2 4 1 0 0 0
Sample Output
4 2
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-4
#define M 1000100
//#define LL __int64
#define LL long long
#define INF 0x7ffffff
#define PI 3.1415926535898
const int maxn = 63;
using namespace std;
int N;
int n, d, m;
struct node
{
int x, y;
double d;
} f[1010];
int dp[maxn][maxn][maxn];
int mp[maxn][maxn][maxn];
bool cmp(node a, node b)
{
return a.d < b.d;
}
void init()
{
N = 0;
for(int i = -5; i <= 5; i++)
{
for(int j = -5; j <= 5; j++)
{
if(i*i + j*j <= 25)
{
f[N].x = i;
f[N].y = j;
f[N++].d = sqrt((i*i*1.0)+(j*j*1.0));
}
}
}
sort(f, f+N, cmp);
}
int Sum(int t, int x, int y, int xx, int yy, int dx, int dy)
{
int cnt = 0;
while(1)
{
cnt += mp[t][xx][yy];
if(x == xx && y == yy)
break;
xx += dx;
yy += dy;
}
return cnt;
}
bool judge(int x, int y)
{
if(x < 0 || x >= n+2*d+1 || y < 0 || y >= n+2*d+1)
return false;
return true;
}
int main()
{
init();
while(cin >>n>>d>>m)
{
if(!n && !d && !m)
break;
int x1, y1, t;
int max_t = 0;
memset(dp, 0, sizeof(dp));
memset(mp, 0, sizeof(mp));
for(int i = 0; i < m; i++)
{
cin >>x1>>y1>>t;
mp[t][x1+d][y1+d] = 1;
max_t = max(max_t, t);
}
max_t++;
for(int tt = 1; tt < max_t; tt++)
{
for(int x = 0; x < 2*d+n+1; x++)
{
for(int y = 0; y < 2*d+n+1; y++)
{
for(int i = 0; i < N && double(d) >= f[i].d; i++)
{
int dx = f[i].x;
int dy = f[i].y;
int xx = x+dx;
int yy = y+dy;
if(!judge(xx, yy))
continue;
int ans;
if(i == 0)//(0,0)這種情況
ans = mp[tt][x][y];
else
{
int s = __gcd(abs(dx), abs(dy));
dx /= s;
dy /= s;
ans = Sum(tt, xx, yy, x, y, dx, dy);
}
dp[tt+1][xx][yy] = max(dp[tt][x][y]+ans, dp[tt+1][xx][yy]);
}
}
}
}
int Max = 0;
for(int i = d; i < d+n; i++)
for(int j = d; j < d+n; j++)
if(Max < dp[max_t][i][j])
Max = dp[max_t][i][j];
cout<<Max<<endl;
}
return 0;
}
相關文章
- POJ 3744 概率dp+矩陣矩陣
- 車身小傷處理技巧及方法
- 影象處理 二維小波變換
- 防抖動處理和節流 小技巧
- 懶人的小技巧, 批處理修改IP
- 安全運維小技巧運維
- pat處理輸入輸出小技巧(待更新)
- poj3017 dp+單調佇列佇列
- 【封裝小技巧】列表處理函式的封裝封裝函式
- 處理多維度變化——橋接模式(三)橋接模式
- 程式設計小技巧之 Linux 文字處理命令(二)程式設計Linux
- 【封裝小技巧】數字處理函式的封裝封裝函式
- POJ 3411 Paid Roads(搜尋的小技巧)AI
- Data Guard維護管理三之處理archivelog gapHive
- POJ 2251-Dungeon Master(BFS-三維迷宮)AST
- 圖觀™引擎開發小技巧——三維場景地標點繪製
- CSS 小數 處理CSS
- Linux文字處理技巧分享Linux
- photoshop常用圖片處理技巧
- 二進位制處理技巧
- 【轉載】SHELL字串處理技巧(${}、##、%%)字串
- 分組(狀壓dp+技巧:快速列舉子集)
- 小技巧:不用任何媒體處理軟體進行視訊壓縮
- Liunx運維(三)-檔案過濾及內容編輯處理運維
- 處理網路連結故障技巧
- 二、淺談 JSON 處理技巧JSON
- 處理字串的小程式字串
- Flask開發技巧之異常處理Flask
- YYImage 原始碼剖析:圖片處理技巧原始碼
- 處理 JS 中 undefined 的 7 個技巧JSUndefined
- 點贊處理的一些小技巧
- 如何處理ARP的攻擊技巧
- 關於strace 工具處理問題技巧
- 微信小程式資料處理微信小程式
- Transact-SQL處理小數SQL
- 小程式程式碼打包處理
- dos批處理命令小記
- POJ 2443Set Operation(好題! 每32位壓縮處理)