[hdoj]1244记忆化搜索

题解参考:http://www.cnblogs.com/peaceful-andy/archive/2012/08/14/2638907.html

很久很久以前……我一直以为记忆化搜索就是dp,dp就是记忆化搜索……多么悲哀的认识……

动态规划是“填表格”的顺序依次递推,记忆化搜索说白了就是搜索的一种,树型,二者的相同点就是,边运行边记忆,对于计算过的都存起来,不再重复计算。

 1 #include <iostream>
 2 using namespace std;
 3
 4 const int N = 1005;
 5 const int M = 25;
 6 int ans[N][M],segs[M],ints[N];
 7 int n,m;
 8
 9 int DFS(int posInt,int posSeg)
10 {
11     if (ans[posInt][posSeg] != -1)
12         return ans[posInt][posSeg];
13     //已经用完了n个数 或 分完m个数段了
14     if (posSeg > m || posInt > n)
15     {
16         ans[posInt][posSeg] = 0;
17         return ans[posInt][posSeg];
18     }
19     //判断,即使取了posInt位置的数,能不能取完余下的数段
20     int remainedInts = n - posInt + 1;
21     int remainedSegs = 0;
22     for (int i = posSeg;i <= m;i ++)
23         remainedSegs += segs[i];
24     //余下的数段的长度之和比余下的数字的个数还大
25     if (remainedSegs > remainedInts)
26     {
27         ans[posInt][posSeg] = 0;
28         return ans[posInt][posSeg];
29     }
30     //若能走到这一步,说明posInt位置的数可以不作为第posSeg个数段的起始数字
31     int max;
32     //以第posInt个数为起始,取seg[posSeg]个连续的数的和
33     int sum = 0;
34     for (int i = posInt;i < posInt + segs[posSeg];i ++)
35         sum += ints[i];
36     max = sum + DFS(posInt + segs[posSeg],posSeg + 1);
37     //以第posInt + 1个数为起始,取seg[posSeg]个连续的数的和
38     int temp = DFS(posInt + 1,posSeg);
39     max = max > temp ? max : temp;
40     ans[posInt][posSeg] = max;
41     return ans[posInt][posSeg];
42 }
43
44 int main ()
45 {
46     while (scanf("%d",&n) != -1 && n != 0)
47     {
48         memset(ans,-1,sizeof(ans));
49         scanf("%d",&m);
50         for (int i = 1;i <= m;i ++)
51             scanf("%d",&segs[i]);
52         for (int i = 1;i <= n;i ++)
53             scanf("%d",&ints[i]);
54         printf("%d\n",DFS(1,1));
55     }
56     return 0;
57 }

hdoj1244

思路:

第一次,只用了简单地深搜,超时。于是自然就想到记忆搜索,用了就过啦。

ints是一维数组,保存所有数字。segs是一位数组,保存所有数段的长度。

ans是二维数组。ans[i][j]保存以第i个数字开始(但第i个数字不一定被取到,只是从第i个数字开始考虑),计算j,j+1...m段数段之和的最大值。(①划分子问题)本题要求的便是ans[1][1]。

ans[i][j]=max{sum+ans[i+segs[j]][j+1],ans[i+1][j]}。(②写递推关系式)max{}中的两个数的区别就在于,是否以第i个数作为第j个数段的起始数字。

——————————

dfs模板://记忆化搜索的精髓就是*里面的啦*

如果达到边界就*保存状态*并return;

如果不符合要求就*保存状态*并return;

状态转移方程进行选择;

*保存状态*并return;

——————————

另:学姐说

if else会比 ?: 慢很多,能用后者不用前者!

时间: 2025-01-20 04:24:48

[hdoj]1244记忆化搜索的相关文章

HDU 1248寒冰王座-全然背包或记忆化搜索

寒冰王座 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 13001    Accepted Submission(s): 6620 Problem Description 不死族的巫妖王发工资拉,死亡骑士拿到一张N元的钞票(记住,仅仅有一张钞票),为了防止自己在战斗中频繁的死掉,他决定给自己买一些道具,于是他来到了地精商店前. 死亡骑

HDU 3779 Railroad(记忆化搜索)

Railroad Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submission(s) : 10   Accepted Submission(s) : 3 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description A train yard is a complex ser

Count the string(记忆化搜索)

Count the string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4899    Accepted Submission(s): 2313 题目连接 Problem Description It is well known that AekdyCoin is good at string problems as well

HDU 1248寒冰王座-完全背包或记忆化搜索

寒冰王座 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 13001    Accepted Submission(s): 6620 Problem Description 不死族的巫妖王发工资拉,死亡骑士拿到一张N元的钞票(记住,只有一张钞票),为了防止自己在战斗中频繁的死掉,他决定给自己买一些道具,于是他来到了地精商店前. 死亡骑士

HDU 1513 Palindrome:LCS(最长公共子序列)or 记忆化搜索

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1513 题意: 给你一个字符串s,你可以在s中的任意位置添加任意字符,问你将s变成一个回文串最少需要添加字符的个数. 题解1(LCS): 很神奇的做法. 先求s和s的反串的LCS,也就是原串中已经满足回文性质的字符个数. 然后要变成回文串的话,只需要为剩下的每个落单的字符,相应地插入一个和它相同的字符即可. 所以答案是:s.size()-LCS(s,rev(s)) 另外,求LCS时只会用到lcs[i-

uva 1076 - Password Suspects(AC自动机+记忆化搜索)

题目链接:uva 1076 - Password Suspects 题目大意:有一个长度为n的密码,存在m个子串,问说有多少种字符串满足,如果满足个数不大于42,按照字典序输出. 解题思路:根据子串构建AC自动机,然后记忆化搜索,dp[i][u][s]表示第i个字符,在u节点,匹配s个子串. #include <cstdio> #include <cstring> #include <queue> #include <string> #include <

poj 1579(动态规划初探之记忆化搜索)

Function Run Fun Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 17843   Accepted: 9112 Description We all love recursion! Don't we? Consider a three-parameter recursive function w(a, b, c): if a <= 0 or b <= 0 or c <= 0, then w(a, b

记忆化搜索,FatMouse and Cheese

1.从gird[0][0]出发,每次的方向搜索一下,每次步数搜索一下 for(i=0; i<4; i++) { for(j=1; j<=k; j++) { int tx=x+d[i][0]*j; int ty=y+d[i][1]*j; if(tx>=0&&tx<n&&ty>=0&&ty<n&&grid[x][y]<grid[tx][ty]) { int temp=memSearch(tx,ty); i

LightOJ1417 Forwarding Emails(强连通分量+缩点+记忆化搜索)

题目大概是,每个人收到信息后会把信息发给他认识的一个人如此下去,问一开始要把信息发送给谁这样看到信息的人数最多. 首先找出图中的SCC并记录每个SCC里面的点数,如果传到一个SCC,那么里面的人都可以看到信息. 然后SCC缩点后就形成DAG,直接记忆化搜索,d(u)搜索从u点出发开始传最多能传多少人. 最后就是找答案了. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namesp