zoj 1558 - Euro Efficiency

来源:互联网 发布:皇甫圣华的淘宝店 编辑:程序博客网 时间:2024/06/05 03:18

题目:给你6中面值的货币,统计组成1~100面值需要的最小平均货币数量,以及所有值中使用最多货币的数量。

分析:dp,搜索,松弛迭代。6种货币面值可能有负的。

            解法1:可利用利用完全背包求解;

            因为货币可能为负,所以可能是与超过100的面值“相加”的结果,所以扩大容量即可;

            解法2:利用松弛迭代,松弛每种货币的使用基础货币的数量,不能更新即可;

            使用bfs从6种基础货币开始搜索,数量已定位递增,每个面值找到时一定是组成最少的;

            扩展半径控制到100(0~300)即可。

说明:(2011-09-19 10:06)。

背包解法:

#include <stdio.h> #include <iostream> using namespace std; int F[ 205 ];int C[ 7 ];int main(){    int T;    while ( ~scanf("%d",&T))    while ( T -- ) {        for ( int i = 1 ; i <= 6 ; ++ i )            scanf("%d",&C[ i ]);                    for ( int i = 0 ; i <= 200 ; ++ i )            F[ i ] = i;                for ( int k = 0 ; k <= 100 ; ++ k )        for ( int i = 6 ; i >= 1 ; -- i ) {            for ( int j = 200 ; j >= C[ i ] ; -- j )                if ( F[ j ] > F[ j-C[ i ] ] + 1 )                    F[ j ] = F[ j-C[ i ] ] + 1;            for ( int j = 0 ; j <= 200-C[ i ] ; ++ j )                if ( F[ j ] > F[ j+C[ i ] ] + 1 )                    F[ j ] = F[ j+C[ i ] ] + 1;        }            int Sum = 0,Max = 0;        for ( int i = 1 ; i <= 100 ; ++ i ) {            Sum += F[ i ];            if ( Max < F[ i ] )                 Max = F[ i ];        }                printf("%d.%d %d\n",Sum/100,Sum%100,Max);    }    return 0;}
松弛解法:
#include<iostream>#include<cstdlib>using namespace std;int coin[ 6 ];int sign[ 301 ];int leat[ 301 ];int queu[ 301 ];int main(){     int t;    cin >> t;    while ( t -- ) {        for ( int i = 0 ; i < 6 ; ++ i )            cin >> coin[ i ];                    memset( sign , 0 , sizeof( sign ) );        for ( int i = 0 ; i < 6 ; ++ i ) {            sign[ coin[ i ]+100 ] = 1;            leat[ coin[ i ]+100 ] = 1;            queu[ i ] = coin[ i ]+100;        }                int move = 0,save = 6;        while ( move < save ) {            int p = queu[ move ];            for ( int k = 0 ; k < 6 ; ++ k ) {                /* 增加 */                int q = p + coin[ k ];                if ( q >= 0 && q < 301 && !sign[ q ] ) {                    sign[ q ] = 1;                    queu[ save ++ ] = q;                    leat[ q ] = leat[ p ] + 1;                }                /* 减少 */                    q = p - coin[ k ];                if ( q >= 0 && q < 301 && !sign[ q ] ) {                    sign[ q ] = 1;                    queu[ save ++ ] = q;                    leat[ q ] = leat[ p ] + 1;                }            }            ++ move;                }                 double sum = 0.0;        int    max = 0;        for ( int i = 101 ; i < 201 ; ++ i ) {            sum += leat[ i ];            if ( leat[ i ] > max )            max = leat[ i ];             }        printf("%.2f %d\n",sum/100.0,max);    }    return 0; }

0 0
原创粉丝点击