1. 程式人生 > >Too Rich ICPC 2015 Changchun A dfs+思維

Too Rich ICPC 2015 Changchun A dfs+思維

9255: Too Rich

時間限制: 1 Sec  記憶體限制: 128 MB 提交: 100  解決: 22 [提交] [狀態] [討論版] [命題人:admin]

題目描述

You are a rich person, and you think your wallet is too heavy and full now. So you want to give me some money by buying a lovely pusheen sticker which costs p dollars from me. To make your wallet lighter, you decide to pay exactly p dollars by as many coins and/or banknotes as possible. For example, if p = 17 and you have two $10 coins, four $5 coins, and eight $1 coins, you will pay it by two $5 coins and seven $1 coins. But this task is incredibly hard since you are too rich and the sticker is too expensive and pusheen is too lovely, please write a program to calculate the best solution.

輸入

The first line contains an integer T indicating the total number of test cases. Each test case is a line with 11 integers p, c1 , c5 , c10 , c20 , c50 , c100 , c200 , c500 , c1000 , c2000 , specifying the price of the pusheen sticker, and the number of coins and banknotes in each denomination. The number c i means how many coins/banknotes in denominations of i dollars in your wallet. 1≤T≤20000 0≤p≤109 0≤c i≤100000

輸出

For each test case, please output the maximum number of coins and/or banknotes he can pay for exactly p dollars in a line. If you cannot pay for exactly p dollars, please simply output ‘-1‘.

樣例輸入

3
17 8 4 2 0 0 0 0 0 0 0
100 99 0 0 0 0 0 0 0 0 0
2015 9 8 7 6 5 4 3 2 1 0

樣例輸出

9
-1
36

來源/分類

[提交] [

狀態]

遺憾,比賽時想到了正確的解法,但是種種原因,最後沒寫。。。

題意:有十種面額的硬幣的對應的個數,給一個錢數n,求恰好等於n且硬幣個數最多的結果

開始直接寫了貪心,然後發現貪不過去

樣例在這裡:250 1 0 0 3 1 0 1 0 0 0  答案是2,貪心是-1

                     190 0 0 0 5 100 0 0 0 0 0  答案是5,貪心應該還是-1

然後想了下dfs,但是細節不太會寫

思路:算出所給的所有的錢數,減去要求的n,接著用這個減去的值m求硬幣個數最少的情況,最後相減就可以

這個dfs好寫一些,但是一直處在dfs能看懂但自己寫不出來的狀態。。。

程式碼:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=50;
const int inf=0x3f3f3f3f;
ll num[20];
ll val[20]={0,1,5,10,20,50,100,200,500,1000,2000};
ll use[20];
ll ans;
void dfs(int x,ll sum,ll cnt){
    if(!sum){
        ans=min(ans,cnt);
        return ;
    }
    if(x<1) return ;
    use[x]=min(sum/val[x],num[x]);
    dfs(x-1,sum-val[x]*use[x],cnt+use[x]);
    if(use[x]>=1){
        use[x]--;
        dfs(x-1,sum-val[x]*use[x],cnt+use[x]);
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        memset(use,0,sizeof(use));
        ll p,sum=0;
        ll cnt=0;
        scanf("%lld",&p);
        for(int i=1; i<=10; i++){
            scanf("%lld",&num[i]);
            sum+=num[i]*val[i];
            cnt+=num[i];
        }
        sum-=p;
        if(sum<0){
            printf("-1\n");
            continue;
        }
        ans=inf;
        dfs(10,sum,0);
        if(ans==inf){
            printf("-1\n");
        }
        else printf("%lld\n",cnt-ans);
    }
    return 0;
}