动态规划的题目特点以及求“硬币个数最少”
1、计数
-
有多少种方法走到右下角
-
有多少种方法选出K个数使得和是Sum
2、求最大最小值
-
从左上角走到右下角路径的最大数字和
-
最长上升子序列长度
3、求存在性
-
取石子游戏,先手是否取胜
-
能不能选出K个数使得和是SUM
实例一
#include <stdio.h>
#include <stdlib.h>
#define MAX 100000
//你有三种硬币面别是:2元,5元,7元每种硬币足够多
//买一本书需要27元
//如何用最少的硬币组合正好付清,不需要对方找钱
//找见输出硬币个数,找不见返回-1
int fun(int a[],int m,int n){
int *f = (int*)malloc(sizeof(int)*(m+1));
f[0] = 0;
int i,j;
for(i=1;i<=m;i++){
f[i] = MAX;
for(j=0;j<n;j++){
if(i>=a[j] && f[i-a[j]] != MAX){
f[i] = (f[i-a[j]]+1) > f[i]?f[i]:(f[i-a[j]]+1);
}
}
}
if(f[m] == MAX){
f[m] = -1;
}
return f[m];
}
int main() {
int a[3] = {2,5,7},m=27;
int n = sizeof(a)/sizeof(int);
int min = fun(a,m,n);//钱的面值,总钱,面值钱的种数
printf("%d",min);
return 0;
}
确定状态 -> 看最后一步,化成子问题
转移方程->想法转换Wie式子
初始条件和边界情况->用转换方程算不出来,需要手动定义
消除冗余加速计算唉