动态规划算法--币值最大化(c++实现)
币值最大化的问题描述如下:给定n个硬币,其面值均为正整数c1,c2,…,cn,请问如何选择硬币,使得在其原始位置互不相邻的条件下,所选硬币的总金额最大,并且找出组成最大币值所包含的所有硬币!
解题思路分析:
1.最大金额用F(n)表示,然后找到F(n)的递推关系,我们可以分成两组:一组是包含最后一个硬币的,另一组是不包含最后一个硬币的。
2.那第一组:F(n) = cn+F(n-2);//第n个币包含
第二组:F(n) = F(n-1);//第n个币不包含
即 F(n)=max{cn+F(n-2),F(n-1)},n>1 //比较两种情况并取较大值
3.再结合初始条件:F(0)=0(下标从1开始)0,F(1)=c1
获取最大币值的中心函数如下:
int coinmax(int n)
{
c[0] = 0;//初始化c[0]及f[0]
f[0] = 0;
f[1] = c[1]; //f[]中保存了计算过的每一步的值
for (int i = 2; i <= n; i++)
{
f[i] = max(c[i] + f[i - 2], f[i - 1]);
//获取最大币值
}
return f[n];
}
完整实现代码如下:
#include <iostream>
#define MAX 20
int c[MAX];//存放各个币值的数组,下标0不用
int f[MAX];
int max(int x,int y) //取较大值函数
{
return (x>y)?x:y;
}
int coinmax(int n)
{
c[0] = 0;//初始化c[0]及f[0]
f[0] = 0;
f[1] = c[1]; //f[]中保存了计算过的每一步的值
for (int i = 2; i <= n; i++)
{
f[i] = max(c[i] + f[i - 2], f[i - 1]);
//获取最大币值
}
return f[n];
}
int main()
{
int n;
printf("请输入有多少个纸币:");
scanf("%d", &n);
printf("请分别输入纸币的价值:");
for (int i = 1; i <= n; i++)
{
scanf("%d", &c[i]);
}
int arr[MAX];//定义arr数组表示所选择的硬币
int num = 0;
printf("最大币值为:%d\n", coinmax(n));
for (int i = n; i >= 1; i--)
{
if (f[i] == f[i - 1])//选择了第i-1个,然后再将第i-1个放进arr数组
{
arr[num++] = c[--i];
}
else{
arr[num++] = c[i--];//没有选择第i-1个则将他本身先放入数组,
//然后再将数组c的下标减一,arr的下标加一
}
}
printf("各个币值为:");
for (int i = 0; i<num; i++)
printf("%d ", arr[i]);
}
;
实现效果: