捡硬币问题 动态规划算法C语言实现

问题描述:

现有n个硬币按顺序依次排列在你面前,它们的面值可以看作一个数组coins[]={5,1,2,10,6,2},请在此中选取若干个硬币,使得所取硬币面值总和最大,捡取个数不限,但相邻的硬币不能捡取,请设计相应算法,要求能够输出累加值和选取的硬币序号(硬币面值为正数)

提示:建立数组dp[i]存储选取前i个硬币的累加值

#include
#include
#define N 6
int j=0;
int selectcoins(int c[],int n,int s[])
{
	int i,dp[n];
	dp[0]=0;
	dp[1]=c[0];
	s[j]=1;//因为dp[1]=c[0],暂时选择了第一个硬币,所以暂时给s[0]赋值为1 
	for(i=2;i<=n;i++)
	{
		if(dp[i-2]+c[i-1]>dp[i-1])
		{
			dp[i]=dp[i-2]+c[i-1];
			if(s[j]==i-1) j--;//注意s[j]被赋值后值还可能会变,当满足这种情况时,s[j]会被再次赋值,即新的值覆盖原来的值 
			s[++j]=i;//记录选取硬币的序号 
		}	
		else
		{
			dp[i]=dp[i-1];//这种情况不需要记录新的硬币序号,因为此时dp[i]选取的硬币情况和dp[i-1]一样 
		}
	}
	return dp[--i];//i最后跳出循环时多加了一次1,故还要减一 
} 
int main()
{
	int coins[N]={5,1,2,10,6,2};
	int s[N/2+1]={0};//该数组用来存储选择的硬币序号,因为最多选择N/2+1项,所以数组大小为N/2+1 
	int max,i;
	max=selectcoins(coins,N,s);
	printf("max=%d\n",max);
	printf("选取的硬币编号为:");//硬币编号从1开始 
	for(i=0;i<=j;i++)//输出硬币编号,注意此处是i<=j,而不是i

运行结果 

捡硬币问题 动态规划算法C语言实现_第1张图片 这只是针对一个具体的问题,读者可根据具体问题设置具体参数(代码是自己想的,还有很多可优化之处,后续作者会在空余时间优化代码,以适应更多问题场景,欢迎各位大佬提出宝贵建议。爱你们哦,嘿嘿)

你可能感兴趣的:(算法代码,动态规划,算法,c语言)