标签:
4 12 10 7 5 1
2
这道题目的思路与矩形嵌套有点类似,首先大家可以想到的是要想得到最少的找零硬币数肯定需要知道每一种情况,好,这样可以通过解答树将所有的情况列举出来,但是这样明显会超时,因为情况太多,而且有很多重复的子计算,所以既然要知道每一种情况,用DFS遍历,然后运用记忆化搜索的思想剪枝,将已经得到答案的最小硬币数直接返回不再重复计算
其中dp[i]代表着将i分解成硬币,最少能分成多少个。
/* Problem: NYOJ(南阳理工OJ) Author :2486 Memory: 1012 KB Time: 192 MS Language: C/C++ Result: Accepted */ #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=100000+5; const int INF=0x3f3f3f3f; int n,t,a[maxn],dp[maxn],Min; int dfs(int s) { if(s<0)return INF; if(dp[s]!=-1)return dp[s]; Min=min(s,Min); int ans=INF; for(int i=0; i<n; i++) { ans=min(dfs(s-a[i])+1,ans);//得到最少硬币数 } if(ans!=INF)dp[s]=ans; return ans; } int main() { while(~scanf("%d%d",&n,&t),n&&t) { for(int i=0; i<n; i++) { scanf("%d",&a[i]); } memset(dp,-1,sizeof(dp)); dp[0]=0; Min=INF; dfs(t); if(dp[t]==-1) {//是否可以找零 dfs(t-Min); printf("%d\n",dp[t-Min]);//如果不能,进行再次递归 } else { printf("%d\n",dp[t]); } } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/qq_18661257/article/details/47144189