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;
}