TOJ2273 Making Change ----DFS

題意


就是找零錢, 給定美國貨幣25美分,10美分,5美分,1美分的硬幣個數,以及 需要找的錢,求解恰好找開的 最少硬幣的方案

input


5 9 9 9 37
0 9 9 9 37
10 10 10 0 37
1 3 0 10 30
1 3 6 10 30
0 0 0 0 0

output


Dispense 1 quarters, 1 dimes, 0 nickels, and 2 pennies.
Dispense 0 quarters, 3 dimes, 1 nickels, and 2 pennies.
Cannot dispense the desired amount.
Dispense 0 quarters, 3 dimes, 0 nickels, and 0 pennies.
Dispense 1 quarters, 0 dimes, 1 nickels, and 0 pennies.

思路


當時第一個想法就是貪心,因爲 是硬幣, 記得之前證明過 硬幣類的貪心類問題的可解性, 不幸WA了。。。 後來想了想 硬幣個數有限制,估計這裏會有問題,但是沒有找反例也懶得去翻書證明了。。
然後只能暴力了。。。
直接四重循環或者 四層dfs 都可以;這裏使用dfs
一共分四層,在k層的時候,依次使用0,1,,,num[k]個第k種硬幣,接着繼續dfs(k+1) 直到最後一層;
過程是用臨時數組保存狀態,最後判斷此種狀態可以不可以達到最終的錢數。若能,比較最值。
PS: 有一種剪枝情況: 在循環num[k]的時候,若當前總和已經超過了 總錢數,則剪掉。

代碼


/* Accepted 2273    C++ 1.0K    0'00.00"    852K    */

#include <stdio.h>
int num[4],coin[4]={25,10,5,1},ans[4],tmp[4],Min,flag,money;
/*num爲各個硬幣個數,ans爲最優解,tmp保存當前狀態解,flag標誌是否有解,money爲輸入總錢數*/
void dfs(int k)
{
    if(k>3)
    {
        int n=0,sum=0;
        for(int i=0;i<4;i++)
         {
              n+=tmp[i];
              sum+=tmp[i]*coin[i];
         }
         if(sum==money)
         {
             if(n<=Min)
            {
                for(int i=0;i<4;i++)
                    ans[i]=tmp[i];
                Min=n;
            }
            flag=1;
         }
    }
    else
    {
        for(int i=0;i<=num[k];i++)
        {
            tmp[k]=i;
            //剪枝代碼,若當前 得到的錢數已經超過了總錢數,則不必遞歸
            int sum=0;
            for(int j=0;j<k;j++)
                sum+=coin[j]*tmp[j];
            if(sum>money) break;
            //
            dfs(k+1);
        }
    }
}
int main()
{
     while(scanf("%d%d%d%d%d",&num[0],&num[1],&num[2],&num[3],&money)&&(num[0]+num[1]+num[2]+num[3]+money))
     {
        flag=0;
        Min=num[0]+num[1]+num[2]+num[3]+1;
        dfs(0);
        flag?printf("Dispense %d quarters, %d dimes, %d nickels, and %d pennies.\n",ans[0],ans[1],ans[2],ans[3]):printf("Cannot dispense the desired amount.\n");
     }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章