硬币问题(DAG上的动态规划)
2013-05-01 18:45
239 查看
问题描述:
有n种硬币,面值分别为v1,v2,v3...vn,每种硬币有无限多,给定非负整数s,可以选用多少个硬币,使得面值之和恰好为s?输出硬币数目的最小值和最大值,并且输出各自的选取方案(如果有多种方案,则输出硬币编号字典序较小的方案,输出每种选取方案的面值)。
分析:本质上市一个DAG上的路径问题,我们把每种面值看做一个点,表示还需凑足的面值,则初始状态为0,目标状态为0,若当前在i,则每使用一枚硬币j,状态转移到i-vj。
代码:
上面的代码中,如果不需要输出路径的话,则可以不要max_coins和min_coins数组,下面在写一个递归的。
这个我只写了求最长路径的,如果要求最短路径,则和最长路径类似,在此省略。
有n种硬币,面值分别为v1,v2,v3...vn,每种硬币有无限多,给定非负整数s,可以选用多少个硬币,使得面值之和恰好为s?输出硬币数目的最小值和最大值,并且输出各自的选取方案(如果有多种方案,则输出硬币编号字典序较小的方案,输出每种选取方案的面值)。
分析:本质上市一个DAG上的路径问题,我们把每种面值看做一个点,表示还需凑足的面值,则初始状态为0,目标状态为0,若当前在i,则每使用一枚硬币j,状态转移到i-vj。
代码:
#include<stdio.h> #define N 1100 int v ,min ,max ,min_coins ,max_coins ; void print_ans(int *d,int s, int n) { while(s){ printf("%d ",v[d[s]]); s-=v[d[s]]; } printf("\n"); } int main() { int T,i,j,n,s; scanf("%d",&T); while(T--) { scanf("%d %d",&n,&s); for(i=0;i<n;i++) scanf("%d",&v[i]); min[0]=max[0]=0; for(i=1;i<=s;i++){ min[i]=0x7FFFFFFF; max[i]=-0x7FFFFFFF; } for(i=1;i<=s;i++){ for(j=0;j<n;j++){ if(i>=v[j]){ //min[i]=min[i]<(min[i-v[j]]+1)?min[i]:(min[i-v[j]]+1); if(min[i]>min[i-v[j]]+1){ min[i]=min[i-v[j]]+1; min_coins[i]=j; } if(max[i]<max[i-v[j]]+1){ max[i]=max[i-v[j]]+1; max_coins[i]=j; } //max[i]=max[i]>(max[i-v[j]]+1)?max[i]:(max[i-v[j]]+1); } } } printf("%d %d\n",min[s],max[s]); print_ans(min_coins,s,n); print_ans(max_coins,s,n); } return 0; }
上面的代码中,如果不需要输出路径的话,则可以不要max_coins和min_coins数组,下面在写一个递归的。
#include<stdio.h> #include<string.h> #define N 1100 int v ,d ,vis ; int dp(int s, int n) { int i; if(vis[s]) return d[s]; vis[s]=1; d[s]=-1<<30;//没有算过的我们假定很小 for(i=0;i<n;i++) if(s>=v[i]&&d[s]<dp(s-v[i],n)+1) d[s]=dp(s-v[i],n)+1; return d[s]; } void print_ans(int s,int n){ int i; for(i=0;i<n;i++){ if(s>=v[i]&&d[s]==d[s-v[i]]+1){ printf("%d ",v[i]);//输出所选的银币面值 print_ans(s-v[i],n); break; } } } int main() { int T,i,n,s,ans; scanf("%d",&T); while(T--) { scanf("%d %d",&n,&s); for(i=0;i<n;i++) { scanf("%d",&v[i]); } memset(vis,0,sizeof(vis)); vis[0]=1; d[0]=0;//终点状态药初始化为0,访问过 ans=dp(s,n); printf("%d\n",ans); print_ans(s,n); printf("\n"); } return 0; }
这个我只写了求最长路径的,如果要求最短路径,则和最长路径类似,在此省略。
相关文章推荐
- DAG上的动态规划硬币问题
- DAG上的动态规划------硬币问题
- 硬币问题(字典最小序)-DAG动态规划问题
- DAG上的动态规划--硬币问题
- ACM:DAG上的动态规划------硬币问题
- DAG上的动态规划------硬币问题
- 动态规划-DAG-硬币问题
- DAG上的动态规划(硬币问题)
- Java动态规划之硬币找零问题实现代码
- 动态规划之硬币问题
- 矩形嵌套(最小字典序)—DAG动态规划问题
- 动态规划之硬币找零问题
- 动态规划——最少硬币问题
- 动态规划之硬币组合问题
- 动态规划两题(矩形嵌套+硬币问题)P161-162
- 动态规划-最少硬币问题
- 动态规划----硬币问题
- 矩阵嵌套问题(DAG上的动态规划)
- 动态规划-硬币问题
- 动态规划之硬币表示问题