HNU OJ10086 挤挤更健康 记忆化搜索DP

挤挤更健康
Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB
Total submit users: 339, Accepted users: 216
Problem 10086 : No special judgement
Problem description
用边长小于N的正方形方砖(注意,不要求所有的方砖大小相同,请看样例说明)不重叠地铺满N*N的正方形房间,最少要几块方砖。
Input
第一行是一个整数T,表示测试数据的组数,接下来的T 行,每一行是一个N(2<=N<=100) 
Output
对于每一组测试数据输出一行,为最少需要的块数。
Sample Input
2
4
5
Sample Output
4
8
Judge Tips
当N=4时 最优的铺砖方法 AABB AABB CCDD CCDD A,B,C,D为四块方砖的代号。 其他的铺法,例如: AAAB AAAC AAAD EFGH 需要的8块砖,不是最少的。

题目链接:http://acm.hnu.cn/online/?action=problem&type=show&id=10086

用边长小于N的正方形方砖(注意,不要求所有的方砖大小相同),
不重叠地铺满N*N的正方形房间,最少要几块方砖。可以将n*n的大正方形分成若干的小矩形,
然后对每一个小矩形递归地求解,但是分块方法应该具有普遍性,而且分块数目应该尽量地少。
最好的情况莫过于将正方形分成两块,对于这道题,我们可以考虑将正方形分成n*k和n*(n-k)的两块小矩形,
每一块都恰好被边长小于n的正方形以最优的方式填满(即数目最小的填充方式)。使用动态规划法,可得递归方程

f(x,y)=      1,            x=y,x<n;

f(y,x),       x<y;

min(f(k,y)+f(x-k,y))   (x/2<=k<=x-1)   x>y或者x=y=n;

然后爆搜肯定超时,因为我试过了,所以记忆化搜索下

/*
User: 96655 , Problem : 10086
Language : GNU C++ , Judge Result: Accepted
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long LL;
const int INF=0x3f3f3f3f;
int n;
int a[105][105];
int f(int x,int y)
{
    if(a[x][y]!=-1)return a[x][y];
    if(x==y&&x<n)return a[x][y]=1;
    if(x<y)return a[x][y]=f(y,x);
    int tt=INF;
    for(int i=x/2;i<=x-1;++i)
    {
       tt=min(f(i,y)+f(x-i,y),tt);
    }
    return a[x][y]=tt;
}
int main()
{
   int  T;
    scanf("%d",&T);
    while(T--)
    {
        memset(a,-1,sizeof(a));
        scanf("%d",&n);
        printf("%d\n",f(n,n));
    }
   return 0;
}

时间: 2024-10-10 05:38:22

HNU OJ10086 挤挤更健康 记忆化搜索DP的相关文章

hdu 4960 记忆化搜索 DP

Another OCD Patient Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 490    Accepted Submission(s): 180 Problem Description Xiaoji is an OCD (obsessive-compulsive disorder) patient. This morni

HDU 1078 FatMouse and Cheese(记忆化搜索DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1078 题目大意:一个n*n的图,每个点都有奶酪,老鼠从(0,0)开始走,每次最多只能走k步就要停下来,停下的这个位置的奶酪数只能比上一个停留的位置大,并获取其奶酪,每次只能水平或垂直走,问最多能得到的奶酪. 解题思路:记忆化搜索,这方面还是写的太少,还要看别人才会,这个就当个例子参考吧. 1 #include<cstdio> 2 #include<cstring> 3 #include

hdu1331&amp;&amp;hdu1579记忆化搜索(DP+DFS)

这两题是一模一样的``` 题意:给了一系列递推关系,但是由于这些递推很复杂,所以递推起来要花费很长的时间,所以我要编程序在有限的时间内输出答案. w(a, b, c): 如果a,b,c中有一个值小于等于0,那么w(a, b, c)的值为1 如果a,b,c中有一个值大于20,那么w(a, b, c)的值为w(20, 20, 20) 如果a<b<c,那么w(a, b, c)=w(a, b, c-1) + w(a, b-1, c-1) - w(a, b-1, c) 否则w(a, b, c)=w(a-

HDU 1978 How many ways(第一道记忆化搜索+DP)

How many ways Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4610    Accepted Submission(s): 2726 Problem Description 这是一个简单的生存游戏,你控制一个机器人从一个棋盘的起始点(1,1)走到棋盘的终点(n,m).游戏的规则描述如下: 1.机器人一开始在棋盘的起始点并

记忆化搜索+dp(洛谷1514 引水入城2010noip提高组)

在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城市都有一个海拔高度. 为了使居民们都尽可能饮用到清澈的湖水,现在要在某些城市建造水利设施.水利设施有两种,分别为蓄水厂和输水站.蓄水厂的功能是利用水泵将湖泊中的水抽取到所在城市的蓄水池中. 因此,只有与湖泊毗邻的第1 行的城市可以建造蓄水厂.而输水站的功能则是通过输水管线利用高度落差,将湖水从高处向低处输送.故一座城市能建造输水站

poj-1088-滑雪【记忆化搜索+DP】

滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 83899   Accepted: 31413 Description Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道载一个区域中最长底滑坡.区域由一个二维数组给出.数组的每个数字代表点的高度.下面是一个例子 1 2 3 4 5 16 17

BZOJ2246 [SDOI2011]迷宫探险 【记忆化搜索dp + 概率】

题目 输入格式 输出格式 仅包含一个数字,表示在执行最优策略时,人物活着走出迷宫的概率.四舍五入保留3位小数. 输入样例 4 3 3 2 .$. A#B A#C @@@ 143 37 335 85 95 25 223 57 输出样例 0.858 提示 题解 毒瘤dp题 我们设\(f[x][y][s][h]\)表示从点\((x,y)\)出发,所有陷阱状态为\(s\),生命值为\(h\),存活的期望概率 我们枚举邻点,选择存活概率最大的作为当前\(f\)的值 除了墙,有以下情况: ①如果是空地或者终

UVA - 10891 Game of Sum(记忆化搜索 dp)

#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; int a[100+10]; int dp[120][120]; int sum[120]; int vis[120][120]; int dfs(int f,int t) { int i,j,k; if(vis[f][t]==

HDU 1078 FatMouse and Cheese (记忆化搜索+dp)

详见代码 1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <memory.h> 5 using namespace std; 6 const int inf=0x3f3f3f3f; 7 int a[110][110]; 8 int dp[110][110];//表示到i,j的最大路径和 9 int dir[4][2]= {1,0,-1,0,0,1,0,-1};