动态规划经典问题

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

动态规划经典问题

1、三角数塔问题

设有一个三角形的数塔,顶点为根结点,每个结点有一个整数值。从顶点出发,可以向左走

或向右走,如图所示:

要求从根结点开始,请找出一条路径,使路径之和最大,只要输出路径的和。

【代码】

//

// 例题1 三角数字塔问题//

//

#include

#include

#define MAXN 101

intn,d[MAXN][MAXN];

int a[MAXN][MAXN];

voidfnRecursive(int,int);

//递推方法函数声明

intfnMemorySearch(int,int);

//记忆化搜索函数声明

int main()

{

inti,j;

printf("输入三角形的行数n(n=1-100):\n");

scanf("%d",&n);

printf("按行输入数字三角形上的数(1-100):\n");

for(i=1; i<=n; i++)

for(j=1; j<=i; j++)

scanf("%d",&a[i][j]);

for(i=1; i<=n; i++)

for(j=1; j<=i; j++)

d[i][j]=-1;//初始化指标数组

printf("递推方法:1\n记忆化搜索方法:2\n");

int select;

scanf("%d",&select);

if(select==1)

{

fnRecursive(i,j);//调用递推方法

printf("\n%d\n",d[1][1]);

}

if(select==2)

{

printf("\n%d\n",fnMemorySearch(1,1));//调用记忆化搜索方法}

else

printf("输入错误!");

return 0;

}

voidfnRecursive(inti,int j)

//递推方法实现过程

{

for(j=1; j<=n; j++)

d[n][j]=a[n][j];

for(i=n-1; i>=1; i--)

for(j=1; j<=i; j++)

d[i][j]=a[i][j]+(d[i+1][j]>d[i+1][j+1]?d[i+1][j]:d[i+1][j+1]); }

intfnMemorySearch(inti,int j)

//记忆化搜索实现过程

{

if(d[i][j]>=0) return d[i][j];

if(i==n) return(d[i][j]=a[i][j]);

if(fnMemorySearch(i+1,j)>fnMemorySearch(i+1,j+1))

return(d[i][j]=(a[i][j]+fnMemorySearch(i+1,j)));

else

return(d[i][j]=(a[i][j]+fnMemorySearch(i+1,j+1)));

}

2、硬币问题

问题描述:有n种硬币,面值分别为V1,V2,…,Vn, 每种有无限多。给定非负整数S,可以选用多少硬币,使得面值之和恰好为S,输出硬币数目的最小值和最大值。

(1<=n<=100,0<=S<=10000,1<=Vi<=S)

【代码】

//

// 例题1 硬币问题//

//

#include

#include

#define INF 100000000

#define MAXNUM 10000

#define MONEYKIND 100

intn,S;

int V[MONEYKIND];

int min[MAXNUM],max[MAXNUM];

voiddp(int*,int*);

//递推方法函数声明

voidprint_ans(int*,int);

//输出函数声明

int main()

{

inti;

printf("输入硬币的种数n(1-100):\n");

scanf("%d",&n);

printf("输入要组合的钱数S(0-10000):\n");

scanf("%d",&S);

printf("输入硬币种类:\n");

for(i=1; i<=n; i++)

{

scanf("%d",&V[i]);

}

dp(min,max);

printf("最小组合方案:\n");

print_ans(min,S);

printf("\n");

printf("最大组合方案:\n");

print_ans(max,S);

return 0;

}

voiddp(int *min,int *max)

//递推过程实现

{

inti,j;

min[0] = max[0] = 0;

for(i=1; i<=S; i++)//初始化数组

{

min[i]=INF;

max[i]=-INF;

}

for(i=1; i<=S; i++)

for(j=1; j<=n; j++)

if(i>=V[j])

{

if(min[i-V[j]]+1

min[i]=min[i-V[j]]+1;//最小组合过程

//printf("%d\n",min[i]);

}

if(max[i-V[j]]+1>max[i])

max[i]=max[i-V[j]]+1;//最大组合过程

}

}

voidprint_ans(int *d,int S)

//输出函数实现

{

inti;

for(i=1; i<=n; i++)

if(S>=V[i]&&d[S]==d[S-V[i]]+1)

{

printf("%d-",V[i]);

print_ans(d,S-V[i]);

break;

}

}

3、矩形嵌套问题

问题描述:有n个矩形,每个矩形可以用两个整数a,b描述,表示它的长和宽。矩形X(a,b)可以嵌套在矩形Y(c,d)中,当且仅当a

【代码】

//

相关文档
最新文档