递推与动态规划???

cquit 2011-05-16 10:37:52
记忆式的自顶向下的递推<=>动态规划?
1.记忆性。
2.自顶向下性,利用前面的结果。
3.递推公式->规划方程。
...全文
552 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
PegasusWang_ 2013-08-30
  • 打赏
  • 举报
回复
引用 6 楼 superdullwolf 的回复:
cao,要是问题可以求出通项公式,迅速就变成了O(1) 很经典的例子是斐波那契数列,还有阶乘二进制结果里里含有多少个1的问题。
这俩还都有通项公式
cquit 2011-08-06
  • 打赏
  • 举报
回复
搜索暴力,给力,赞同
nuptxxp 2011-05-28
  • 打赏
  • 举报
回复
楼上正解。。。。
今天我又请教了学长,学长直接发给了我四个字:暴力枚举。
这让一直想动态转移方程的我情何以堪啊。。。
pandm 2011-05-28
  • 打赏
  • 举报
回复
非常抱歉,刚才贴了个有错误的代码,现在修正过来了 = =



#include <algorithm>
#include <cstdio>
#include <cstdlib>
using namespace std;

struct Item {
int m;
int p;
};

struct CmpItem {
bool operator()(Item const &x, Item const &y) const {
return x.p < y.p;
}
};



Item g[17];

int N;
bool buy[20];
int restMoney;
int M, M1, M2;
int P;

int best;



int findGift() {
int i;
for (i = N - 1; i >= 0; --i) {
if (!buy[i] && g[i].m <= M2) return g[i].p;
}

return 0;
}




void solve(int x) {
if (x == N) {
int cost = M - restMoney;
if (cost >= M1) {
best = max(best, P + findGift());
} else {
best = max(best, P);

}


return;
}

buy[x] = false;
solve(x+1);

if (restMoney < g[x].m) return;
buy[x]=true;
restMoney -= g[x].m;
P += g[x].p;
solve(x+1);
restMoney += g[x].m;
P -= g[x].p;



}



void input() {
if (scanf("%d %d", &N, &M) != 2) exit(0);
int i;
for (i = 0; i < N; ++i) {
scanf("%d %d", &(g[i].m), &(g[i].p));
}
scanf("%d %d", &M1, &M2);
}



void run() {
sort(g, g + N, CmpItem());
best = -2000000000;
restMoney = M;
P = 0;
solve(0);
printf("%d\n", best);
}





int main() {
while(1) {
input();
run();
}
return 0;
}



pandm 2011-05-28
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 nuptxxp 的回复:]
那楼上给个思路如何,怎样将这个问题抽象为一般的01背包问题
[/Quote]


给个穷举的算法,只有15个东西,所以复杂度大概也就是2^15 * 15 = 491520,所以穷举还是可以接受的吧。。。


#include <algorithm>
#include <cstdio>
#include <cstdlib>
using namespace std;

struct Item {
int m;
int p;
};

struct CmpItem {
bool operator()(Item const &x, Item const &y) const {
return x.p < y.p;
}
};



Item g[17];

int N;
bool buy[20];
int restMoney;
int M, M1, M2;
int P;

int best;



int findGift() {
int i;
for (i = N - 1; i >= 0; --i) {
if (!buy[i] && g[i].m <= M2) return g[i].p;
}

return 0;
}




void solve(int x) {
if (x == N) {
int cost = M - restMoney;
if (cost >= M1) {
P += findGift();
}

best = max(best, P);

return;
}

buy[x] = false;
solve(x+1);

if (restMoney < g[x].m) return;
buy[x]=true;
restMoney -= g[x].m;
P += g[x].p;
solve(x+1);
restMoney -= g[x].m;
P -= g[x].p;



}



void input() {
if (scanf("%d %d", &N, &M) != 2) exit(0);
int i;
for (i = 0; i < N; ++i) {
scanf("%d %d", &(g[i].m), &(g[i].p));
}
scanf("%d %d", &M1, &M2);
}



void run() {
sort(g, g + N, CmpItem());
best = -2000000000;
restMoney = M;
P = 0;
solve(0);
printf("%d\n", best);
}





int main() {
while(1) {
input();
run();
}
return 0;
}



pandm 2011-05-28
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 nuptxxp 的回复:]
那楼上给个思路如何,怎样将这个问题抽象为一般的01背包问题
[/Quote]


我觉得这题用枚举好像就可以做,因为只有15个东西,每个东西要么买要么不买,也就是说,最多只有2^15 = 32768 种情况
nuptxxp 2011-05-28
  • 打赏
  • 举报
回复
那楼上给个思路如何,怎样将这个问题抽象为一般的01背包问题
pandm 2011-05-28
  • 打赏
  • 举报
回复
这种问题没什么讨论的价值,讨论一百次dp的本质也没法提高dp的水平,条条框框的东西都是在有了一定数量的实践以后抽象出来的
nuptxxp 2011-05-28
  • 打赏
  • 举报
回复
给个动态规划的例子吧,01背包问题,大家讨论讨论吧
超市中一共有N(1<=N<=15)种商品,因为超市长时间没有进货,导致每种商品都仅剩下一件。第i种商品的价格为mi(1<=mi<=10^9),它的实用度为pi(0<=pi<=10000)。YM希望购买商品的总花费不超过M(0<=M<=10^9)。同时,超市今天正好有促销活动,只要购买商品的总花费不低于M1(0<=M1<=10^9),超市将赠送一件价格不超过M2(0<=m2<=10^9)的商品。YM希望购买的商品实用度的总和最大。


输入


多组输入数据。每组输入数据第一行有两个整数N和M。接下来N行,第i行有两个整数mi和pi,表示第i件商品的价格和实用度。最后一行有两个整数M1和M2。


输出


每组数据输出一行,在花费不超过M的情况下,购买的商品最大的实用度总和。


样例输入

3 3
1 2
2 4
3 5
3 2


样例输出

9


tanggui2007 2011-05-27
  • 打赏
  • 举报
回复
毫无疑问,楼主没有明确的问题说明,无法实际的讨论
绿色夹克衫 2011-05-18
  • 打赏
  • 举报
回复
比如f(n) = f(n/2) + f(n/2 + 1)的这种递推,用记忆搜索比较合适,从上到下,很明白需要哪些数据,而从下往上推就没有什么目的性。

又比如四边形不等式,必须有了下面的数据,才知道上面的循环从什么地方开始,这时候用递归就非常麻烦了。

[Quote=引用 7 楼 cquit 的回复:]
引用 3 楼 litaoye 的回复:
在某些情况下不太一样,比如用四边形不等式优化DP,这种方式很难转为递归,另外在某些情况下,递归可以只求一部分解,就可以推出最后结果,而从下往上则需要求全解。


3楼说言甚是,可否在详细一点,多举些例子,不甚感激!~~~
[/Quote]
v5 2011-05-18
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 mougaidong 的回复:]
当必须算出所有子问题结果的时候,我们用“自底向上”,当只求我们关心的子问题的时候,我们用“自顶向下”。
[/Quote]

大多情况下,很是相似。。。
递推是有公式可循的,
而动态规划是在从上至下递归的基础上,从下至上分析出来的
cquit 2011-05-18
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 litaoye 的回复:]
在某些情况下不太一样,比如用四边形不等式优化DP,这种方式很难转为递归,另外在某些情况下,递归可以只求一部分解,就可以推出最后结果,而从下往上则需要求全解。
[/Quote]

3楼说言甚是,可否在详细一点,多举些例子,不甚感激!~~~
绿色夹克衫 2011-05-17
  • 打赏
  • 举报
回复
在某些情况下不太一样,比如用四边形不等式优化DP,这种方式很难转为递归,另外在某些情况下,递归可以只求一部分解,就可以推出最后结果,而从下往上则需要求全解。
turing-complete 2011-05-17
  • 打赏
  • 举报
回复
当必须算出所有子问题结果的时候,我们用“自底向上”,当只求我们关心的子问题的时候,我们用“自顶向下”。
keeya0416 2011-05-17
  • 打赏
  • 举报
回复
很多时候动态规划看起来很像递推
但普通的递推是没有最优子结构的
仅仅是通过保存部分数据以避免重复运算
超级大笨狼 2011-05-17
  • 打赏
  • 举报
回复
cao,要是问题可以求出通项公式,迅速就变成了O(1)
很经典的例子是斐波那契数列,还有阶乘二进制结果里里含有多少个1的问题。
cquit 2011-05-16
  • 打赏
  • 举报
回复
???????????不知有何高见???
pppcz003 2011-05-16
  • 打赏
  • 举报
回复
故作神秘

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧