【POJ 3034】 Whac-a-Mole(DP)

【POJ 3034】 Whac-a-Mole(DP)

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 3621   Accepted: 1070

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,
y
2) 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

Source

Nordic 2006

……憋了三天终于憋出来了= =

题目大意:打地鼠……没玩过应该也都见过,地鼠机每秒会有几个洞钻出来地鼠,打中越多分数越高。

先给出n d m三个数,分别表示地鼠机大小(n*n的矩阵,点为洞) 玩家能移动的最远距离d这个下面再解释 地鼠数量m

m个地鼠的给出方式为 x y t

表示第i只地鼠在第t秒从x,y洞钻出。

规则是这样:每次可以从x1,y1移动到x2,y2,要求保证两点间直线距离小于等于d

移动的路线上所有在该秒钻出的地鼠都会被打中。

在第一秒前,锤子可以在任意位置,之后第i秒只能由i-1秒结束时所在位置开始移动

换言之,就是找一个t秒的路径,能满足路径上打到的地鼠数量最多。

前方高能,直接上思路了,只是来求个题意的话就到这里把

————————————————————————————

————————————————————————————

————————————————————————————

————————————————————————————

————————————————————————————

————————————————————————————

————————————————————————————

————————————————————————————

————————————————————————————

————————————————————————————

————————————————————————————

————————————————————————————

做法dp,枚举秒和该秒锤子的起点,然后由该起点为圆心,

d为半径,那么这个圆内的所有点都可以在该秒从这个点到达

画圆的话代码不太好写,可以换种方式

遍历所有与这个点横坐标距离d内还有纵坐标距离d内的点,判断如果超出范围,就跳出

因为这样遍历只会越遍历越远。

然后一个很坑很坑很坑很坑的地方……

, you are able to move your hammer in a straight line to any position (x2,
y2)

move your hammer in a straight line to any position

in a straight line to any position

to any position

any position

any

好了,如果wa的话就去做吧……

附一组数据:

20 5 4
1 0 1
0 1 1
0 5 2
1 6 2

(DISCUSS借的

PS:不光可以负向超出 正向也可以超过n!!!

处理方式就是把0~n移动到5~n+5

然后0~5表示-5~0 n+5~n+10表示正向爆出

代码如下:

#include <iostream>
#include <cmath>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <stack>
#include <list>
#include <algorithm>
#include <map>
#include <set>
#define LL long long
#define Pr pair<int,int>
#define fread() freopen("in.in","r",stdin)
#define fwrite() freopen("out.out","w",stdout)

using namespace std;
const int INF = 0x3f3f3f3f;
const int msz = 10000;
const int mod = 1e9+7;
const double eps = 1e-8;

int mp[12][33][33];
int dp[12][33][33];
int tmp[33][33];
int dirx[] = { 1, 1,-1,-1};
int diry[] = { 1,-1, 1,-1};
int d,n;

int dis(int x1,int y1,int x2,int y2)
{
	return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}

void cal(int t,int x,int y)
{
	int xx,yy;
	for(int i = 0; i <= d; ++i)
		for(int j = 0; j <= d; ++j)
		{
			if(!i && !j)
			{
				dp[t][x][y] += mp[t][x][y];
				tmp[x][y] = dp[t][x][y];
				dp[t+1][x][y] = max(dp[t+1][x][y],dp[t][x][y]);
				//printf("%d:%d,%d %d\n",t,x,y,tmp[x][y]);
				continue;
			}
			if(dis(x,y,x+i,y+j) > d*d) continue;
			for(int k = 0; k < 4; ++k)
			{
				if(!i && dirx[k] < 0) continue;
				xx = x+i*dirx[k];
				if(!j && diry[k] < 0) continue;
				yy = y+j*diry[k];
				if(xx < 0 || xx >= n || yy < 0 || yy >= n) continue;
				int g = __gcd(abs(xx-x),abs(yy-y));
				tmp[xx][yy] = tmp[xx+(x-xx)/g][yy+(y-yy)/g]+mp[t][xx][yy];
				dp[t+1][xx][yy] =  max(dp[t+1][xx][yy],tmp[xx][yy]);
				//printf("%d,%d->%d,%d: %d->%d get:%d\n",x,y,xx,yy,tmp[xx+(x-xx)/g][yy+(y-yy)/g],dp[t+1][xx][yy],mp[t][xx][yy]);
			}
		}
}

int main()
{
	//fread();
	//fwrite();

	int m,x,y,t;
	while(~scanf("%d%d%d",&n,&d,&m) && (n+d+m))
	{
		memset(mp,0,sizeof(mp));
		memset(dp,0,sizeof(dp));
		int tim = 0;
		n += 10;
		while(m--)
		{
			scanf("%d%d%d",&x,&y,&t);
			mp[t][x+5][y+5] = 1;
			tim = max(tim,t);
		}

		for(int i = 1; i <= tim; ++i)
			for(int j = 0; j < n; ++j)
				for(int k = 0; k < n; ++k)
					cal(i,j,k);

		int mx = 0;
		for(int i = 0; i < n; ++i)
			for(int j = 0; j < n; ++j)
				mx = max(mx,dp[tim+1][i][j]);
		printf("%d\n",mx);
	}

	return 0;
}
时间: 2024-10-13 03:26:03

【POJ 3034】 Whac-a-Mole(DP)的相关文章

【POJ 2409】 Let it Bead(Polya)

[POJ 2409] Let it Bead(Polya) Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5378   Accepted: 3596 Description "Let it Bead" company is located upstairs at 700 Cannery Row in Monterey, CA. As you can deduce from the company name, t

【POJ - 3187】Backward Digit Sums(搜索)

-->Backward Digit Sums 直接写中文了 Descriptions: FJ 和 他的奶牛们在玩一个心理游戏.他们以某种方式写下1至N的数字(1<=N<=10). 然后把相邻的数相加的到新的一行数.重复这一操作直至只剩一个数字.比如下面是N=4时的一种例子 3 1 2 4 4 3 6 7 9 16 在FJ回来之前,奶牛们开始了一个更难的游戏:他们尝试根据最后结果找到开始的序列.这已超过了FJ的思考极限. 写一个程序来帮助FJ吧 Input N和最后的和 Output 满足

【Vijos 1327】回文词(DP)

题目描述 回文词是一种对称的字符串——也就是说,一个回文词,从左到右读和从右到左读得到的结果是一样的.任意给定一个字符串,通过插入若干字符,都可以变成一个回文词.你的任务是写一个程序,求出将给定字符串变成回文词所需插入的最少字符数.   比如字符串“Ab3bd”,在插入两个字符后可以变成一个回文词(“dAb3bAd”或“Adb3bdA”).然而,插入两个以下的字符无法使它变成一个回文词. 输入 第一行包含一个整数N,表示给定字符串的长度,3<=N<=5000   第二行是一个长度为N的字符串,

【POJ 2480】Longge&#39;s problem(欧拉函数)

题意 求$ \sum_{i=1}^n gcd(i,n) $ 给定 $n(1\le n\le 2^{32}) $. 链接 分析 用欧拉函数$φ(x)$求1到x-1有几个和x互质的数. gcd(i,n)必定是n的一个约数.若p是n的约数,那么gcd(i,n)==p的有$φ(n/p)$个数,因为要使gcd(i,n)==p,i/p和n/p必须是互质的.那么就是求i/p和n/p互质的i在[1,n]里有几个,就等价于,1/p,2/p,...,n/p里面有几个和n/p互质,即φ(n/p). 求和的话,约数为p

【POJ 2411】Mondriaan&#39;s Dream(状压dp)

[POJ 2411]Mondriaan's Dream(状压dp) Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 14107   Accepted: 8152 Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, after producing the drawings in hi

【POJ 1698】Alice&#39;s Chance(二分图多重匹配)

http://poj.org/problem?id=1698 电影和日子匹配,电影可以匹配多个日子. 最多有maxw*7个日子. 二分图多重匹配完,检查一下是否每个电影都匹配了要求的日子那么多. #include<cstdio> #include<cstring> #include<algorithm> #define N 360 #define M 30 using namespace std; int t,n,m; int g[N][M]; int linker[M

【POJ 1061】青蛙的约会(扩展欧几里得)

[POJ 1061]青蛙的约会(扩展欧几里得) Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 103473   Accepted: 20116 Description 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置.不过青蛙们都是很乐观的,它

【POJ 1286】Necklace of Beads(polya定理)

[POJ 1286]Necklace of Beads(polya定理) Necklace of Beads Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7550   Accepted: 3145 Description Beads of red, blue or green colors are connected together into a circular necklace of n beads ( n <

Python之路【第二篇】:Python基础(一)

Python之路[第二篇]:Python基础(一) 入门知识拾遗 一.作用域 对于变量的作用域,执行声明并在内存中存在,该变量就可以在下面的代码中使用. 1 2 3 if 1==1:     name = 'wupeiqi' print  name 下面的结论对吗? 外层变量,可以被内层变量使用 内层变量,无法被外层变量使用 二.三元运算 1 result = 值1 if 条件 else 值2 如果条件为真:result = 值1如果条件为假:result = 值2 三.进制 二进制,01 八进