首先是入门级别的一维dp。
这个是凑硬币,如果我们有面值为1元、3元和5元的硬币若干枚,如何用最少的硬币凑够11元?
动态规划算法的核心是:每个子问题的状态和状态的转移方程。
状态是:dp[i] ,即凑够i元最少需要的硬币的个数
转移方程是:dp[i] = min(dp[i-C 1 ]+1,dp[i-C 2 ]+1,dp[i-C 3 ]+1,……,dp[i-C j ]+1])
即,每个状态的值都是最小的那个。
#include<stdio.h>
#define min(a,b) a<b?a:b
int main()
{
int c[3]={1,3,5};
int dp[100], i , j , k=999, n;
scanf("%d",&n);
dp[0] = 0;
for( i = 1 ;i <= n ; i++)
{ k = 999;//这里是关键,每次都要重新赋值。
for(j = 0 ; j < 3; j++)//把每种硬币的可能都找一遍
if(i >= c[j])
{
k = min(dp[i-c[j]]+1,k);
// printf("%d %d\n",k ,c[j]);
//这是从三种硬币中找出最小硬币数的那个。
//dp中的数值是,到这个i的硬币数
}
dp[i]=k;
//printf("%d\n",k);
//每次循环之后min都是最小的硬币数。
//这时无法区分他是用怎么的硬币构成
}
for( i = 0 ;i <= n ; i ++)
printf("%d元至少要%d个硬币 \n", i, dp[i]);
}