题目:给你几种不同面值的货币已知数量,求能否组成一个金额,如果有多组输出总数最小的。
分析:dp,背包。首先将小数转化成整数(乘100),然后每个钱币看成一个物品01背包即可。
用一个数组记录每种钱币的使用情况,以及使用的总金钱数。
说明:面值从大到小方向dp,一定先去的最小总数。(2011-09-24 09:55)
#include <stdio.h>
#include <stdlib.h>
#define INF 10000
int coin[ 5 ] = {0,25,10,5,1};
int numb[ 5 ];
int f[ 501 ][ 5 ];
int main()
{
double A,C[ 5 ];
while ( scanf("%lf",&A) != EOF ) {
for ( int i = 1 ; i <= 4 ; ++ i )
scanf("%d",&numb[ i ]);
for ( int i = 0 ; i <= 500 ; ++ i )
for ( int j = 0 ; j <= 4 ; ++ j )
f[ i ][ j ] = INF;
for ( int i = 0 ; i <= 4 ; ++ i )
f[ 0 ][ i ] = 0;
int V = int(100*A+0.5);
for ( int i = 1 ; i <= 4 ; ++ i ) {
for ( int j = numb[ i ] ; j >= 1 ; -- j )
for ( int k = V ; k >= coin[ i ] ; -- k )
if ( f[ k ][ 0 ] > f[ k-coin[ i ] ][ 0 ] + 1 ) {
for ( int l = 0 ; l <= 4 ; ++ l )
f[ k ][ l ] = f[ k-coin[ i ] ][ l ];
f[ k ][ 0 ] += 1;
f[ k ][ i ] += 1;
}
}
if ( f[ V ][ 0 ] == INF )
printf("NO EXACT CHANGE\n");
else {
for ( int i = 1 ; i <= 4 ; ++ i ) {
printf("%d",f[ V ][ i ]);
if ( i == 4 ) printf("\n");
else printf(" ");
}
}
}
return 0;
}