今天再写一下硬币问题 为什么是再呢
这是个很羞耻的话题 昨天写了一遍硬币
在某谷上跑 没错 挂掉了 TLE MD_SB
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
有很多人说硬币问题是贪心去做
如果你遇到的测试点不呢么毒瘤
例1: 硬币的面值是 1 5 10 要凑出15元 min(硬币个数)
解1:(贪心)每次选最大 min=2
显然是可以得到正确答案的
但是如果硬币的面值是
例2:硬币的面值是 1 5 11 要凑出15元 min(硬币个数)
解2:(贪心)每次选最大 min=5
显然这是错误的 min应该等于3 三个五元
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
所以说 以后我们看到硬币问题的时候
一定不要再深陷于贪心 要多考虑几组测试数据
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DP常规思路:1、设计状态 f(n)为n元需要的最少硬币数
2、写状态转移方程
f(n)= min(f(n-1),f(n-5),f(n-11))+1
但是这题我们要注意一下 不能直接把状态转移方程带入
因为如果n=4 呢n-5,n-11是不是小于零啊
这时候我们加一个中间变量和判断就ojbk了
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
现在我们代码实现一下:
-
#include<iostream>
-
#include<cstdio>
-
#define N 2333333
-
using namespace std;
-
int dp[100010],cost,m;
-
int min(int x,int y){
-
return x>=y?y:x;
-
}
-
-
int main(){
-
scanf("%d",&m);
-
cost=N;
-
dp[0]=0;
-
for(int i=1;i<=m;i++)
-
{
-
dp[i]=N;
-
if(i-1 >= 0) dp[i]=min(dp[i],dp[i-1]+1);
-
if(i-5 >= 0) dp[i]=min(dp[i],dp[i-5]+1);
-
if(i-11 >= 0) dp[i]=min(dp[i],dp[i-11]+1);
-
printf("dp[%d] =%d ",i,dp[i]);
-
}
-
//tmd终于过了 2018年8月5日 10:56
-
return 0;
-
}