hdu ---(4517)小小明系列故事——游戏的烦恼(Dp)

小小明系列故事——游戏的烦恼

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 841    Accepted Submission(s): 296

Problem Description

 
 小小明最近在玩一款游戏,它由n*m大小的矩阵构成,矩阵上会随机产生一些黑色的点,这些点它们可能会连在一起也可能会分开,这些点的个数没有限制,但
是每个1*1方格中最多只可能有一个黑点产生。游戏要求玩家以最短的时间用x*y的小矩阵覆盖这个大矩阵,覆盖的要求有以下2点:
  1. x*y大小的小矩阵内必须有x*y个黑点。
  2. 多个小矩阵可以重叠,但是每个小矩阵放置的位置必须是独一无二的,即不同的小矩阵内的黑点不能完全相同。例如1*2的矩阵可以横着放,也可以竖着放,这两种方法是不同的,即使它们可能共用黑点。
  小小明是个粗心的孩子,他尝试了很多遍都无法将所有的符合要求的小矩阵找到,聪明的你,能不能告诉烦恼中的小小明这个大矩阵里有多少个满足要求的小矩阵呢?

Input

题目有多组测试数据(不多于100个);
每组测试数据的第一行包含2个正整数n和m,然后第二行是x和y(n,m,x,y的意思如题),接下来n行,每行m个字符,其中’ * ’表示黑点,’ . ’表示空白。
n和m为0则结束输入。

[Technical Specification]
0 < n, m <= 2000
0 < x, y <= 1000

Output

请计算并输出一共有多少个满足要求的小矩阵,每组输出占一行。

Sample Input

2 3
1 2

**.

.**

0 0

Sample Output

3

Source

2013腾讯编程马拉松初赛第三场(3月23日)

刚开始进行了个普通的匹配,O(∩_∩)O~,就知道会TLE,╮(╯▽╰)╭,就是这么无奈呀!

贴一下自己丑陋的代码吧..

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 using namespace std;
 5 const int maxn=2005;
 6 char map[maxn][maxn];
 7 int n,m;
 8 bool match(int posx,int posy,int x,int y)
 9 {
10     int i,j;
11     if(posx+x>n||posx<0||posy+y>m||posy<0)
12         return 0;
13     for( i=posx; i<posx+x ; i++ ){
14       for( j=posy ; j<posy+y ; j++ ) {
15          if(map[i][j]!=‘*‘)return false;
16       }
17     }
18   return true;
19 }
20
21 int work(int x,int y)
22 {
23   int i,j,cnt=0;
24   for(i=0;i<n;i++){
25       for(j=0;j<m;j++){
26      if(match(i,j,x,y)) cnt++;
27      if(match(i,j,y,x)) cnt++;
28     }
29   }
30   return cnt;
31 }
32 int main()
33 {
34   int x,y,i;
35   while(scanf("%d%d",&n,&m)!=EOF,n+m!=0)
36   {
37       scanf("%d%d",&x,&y);
38       for(i=0;i<n;i++)
39        scanf("%s",map[i]);
40     printf("%d\n",work(x,y));
41   }
42  return 0;
43 }

然后统计了一下,dp...简单的dp

代码: 不过依旧还是很挫,写到了680ms....

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 using namespace std;
 5 const int maxn=2005;
 6 char map[maxn][maxn];
 7 int dp[maxn][maxn];
 8 int n,m;
 9 void init()
10 {
11   int i,j,cnt=0;
12   memset(dp,0,sizeof(dp));
13   for(i=1;i<=n;i++) {
14       for(j=1;j<=m;j++) {
15       if(map[i][j-1]==‘*‘)cnt++;
16         dp[i][j]=cnt+dp[i-1][j];
17     }
18     cnt=0;
19   }
20 }
21 int work(int x,int y){
22   int i,j,cnt=0;
23   for(i=1;i+x<=n;i++){
24       for(j=1;j+y<=m;j++){
25       int tem=dp[i+x][j+y]-dp[i-1][j+y]-dp[i+x][j-1]+dp[i-1][j-1];
26       if(tem==((x+1)*(y+1)))cnt++;
27     }
28   }
29   return cnt;
30 }
31 int main()
32 {
33   int x,y,i;
34   while(scanf("%d%d",&n,&m),n+m!=0)
35   {
36       scanf("%d%d",&x,&y);
37       x--,y--;
38       for(i=1;i<=n;i++)
39       scanf("%s",map[i]);
40       init();
41     if(x==y) printf("%d\n",work(x,y));
42     else printf("%d\n",work(x,y)+work(y,x));
43
44   }
45  return 0;
46 }

时间: 2024-08-26 18:37:28

hdu ---(4517)小小明系列故事——游戏的烦恼(Dp)的相关文章

HDU 4517 小小明系列故事---游戏的烦恼 (模拟题)

问题描述 : 小小明最近在玩一款游戏,它由n*m大小的矩阵构成,矩阵上会随机产生一些黑色的点,这些点它们可能会连在一起也可能会分开,这些点的个数没有限制,但是每个1*1方格中最多只可能有一个黑点产生.游戏要求玩家以最短的时间用x*y的小矩阵覆盖这个大矩阵,覆盖的要求有以下2点: 1.  x*y大小的小矩阵内必须有x*y个黑点. 2. 多个小矩阵可以重叠,但是每个小矩阵放置的位置必须是独一无二的,即不同的小矩阵内的黑点不能完全相同.例如1*2的矩阵可以横着放,也可以竖着放,这两种方法是不同的,即使

hdu 4506 小明系列故事——师兄帮帮忙

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4506 题目大意:找规律,判断k的t次幂前面的系数. 1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 5 __int64 fun(__int64 a,__int64 b) 6 { 7 __int64 s=1; 8 while (b) 9 { 10 if (b%2==1) 11 s=s*a%1000000

HDU 4502 吉哥系列故事——临时工计划(DP)

Problem Description 俗话说一分钱难倒英雄汉,高中几年下来,吉哥已经深深明白了这个道理,因此,新年开始存储一年的个人资金已经成了习惯,不过自从大学之后他不好意思再向大人要压岁钱了,只能把唯一的希望放到自己身上.可是由于时间段的特殊性和自己能力的因素,只能找到些零零碎碎的工作,吉哥想知道怎么安排自己的假期才能获得最多的工资. 已知吉哥一共有m天的假期,每天的编号从1到m,一共有n份可以做的工作,每份工作都知道起始时间s,终止时间e和对应的工资c,每份工作的起始和终止时间以天为单位

hdu 4511 小明系列故事——女友的考验

小明系列故事——女友的考验 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 822    Accepted Submission(s): 176 Problem Description 终于放寒假了,小明要和女朋友一起去看电影.这天,女朋友想给小明一个考验,在小明正准备出发的时候,女朋友告诉他,她在电影院等他,小明过来的路线必须满足给定的规则

HDU 4511 小明系列故事——女友的考验 (AC自动机+DP)

小明系列故事--女友的考验 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 1734    Accepted Submission(s): 466 Problem Description 终于放寒假了,小明要和女朋友一起去看电影.这天,女朋友想给小明一个考验,在小明正准备出发的时候,女朋友告诉他,她在电影院等他,小明过来的路线必须满足给定的规

HDU - 4511 小明系列故事――女友的考验(AC自动机+DP)

Description 终于放寒假了,小明要和女朋友一起去看电影.这天,女朋友想给小明一个考验,在小明正准备出发的时候,女朋友告诉他,她在电影院等他,小明过来的路线必须满足给定的规则: 1.假设小明在的位置是1号点,女朋友在的位置是n号点,则他们之间有n-2个点可以走,小明每次走的时候只能走到比当前所在点编号大的位置: 2.小明来的时候不能按一定的顺序经过某些地方.比如,如果女朋友告诉小明不能经过1 -> 2 -> 3,那么就要求小明来的时候走过的路径不能包含有1 -> 2 ->

AC自动机 + 二维最短路 HDU 4511 小明系列故事――女友的考验

这个题还是比较好想的. 首先将所有不可行方案建立AC自动机,然后跑最短路. 首先将小明放在(sta = 0,pos = 0)处,sta表示AC自动机上点的编号,pos表示坐标点的编号. 根据pos枚举下一次可以到达的地方[pos+1,n],然后sta在自动机上移动,如果某一步会使sta位于有标记的节点,那么这一步是不可行. #include <iostream> #include<time.h> #include<stdio.h> #include<string.

HDU 4528 小明系列故事――捉迷藏

广搜. 根据题意,可以知道状态总共有$4*n*m$种.每一个位置四种状态:两个都没有发现:发现$E$没发现$D$:发现$D$没发现$E$:两个都发现. 每次移动的花费都是$1$,队列里面状态的费用是单调不减的,所以第一次符合要求的位置就是答案. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath&g

hdu 4528 小明系列故事——捉迷藏

一开始很疑惑自己为什么错了,后来才知道原来这题是可以往回 走的.开4维visit数组记录状态,状态不同则往回走,相同再往回走. 1 30 31 95 S.............................. ..X............................ ...X........................... ....X.......................... .....X......................... ......X........