CF1934B Yet Another Coin Problem 題解
題意
目前有 \(5\) 種硬幣,面值分別為 \(1,3,6,10,15\)。給你一個數字 \(n\),求出可以湊出 \(n\) 的最少的硬幣的數量。
思路
這道題,大多數的人大概會想到動態規劃的方法。
但是,我們應該有敢於創新的精神。於是我就想到了一個簡單的數學方法。
首先我們先不討論面值等於 \(15\) 元的硬幣。
考慮硬幣的面值為 \(1\) 元、\(3\) 元、\(6\) 元、\(10\) 元、\(15\) 元的情況。
1:面值為 \(1\) 元的硬幣的數量範圍小於 \(3\)。
當使用大於等於 \(3\) 個 \(1\) 元硬幣。
則可以用面值為 \(3\) 的硬幣代替。
2:面值為 \(3\) 元的硬幣的數量範圍小於 \(2\)。
當使用大於等於 \(2\) 個 \(3\) 元硬幣。
則可以用面值為 \(6\) 的硬幣代替。
3:面值為 \(6\) 元的硬幣的數量範圍小於 \(4\)。
當使用大於等於 \(4\) 個 \(6\) 元硬幣。
則可以用 \(2\) 個面值為 \(10\) 加 \(1\) 個面值為 \(3\) 加 \(1\) 個面值為 \(1\) 的硬幣代替。
4:面值為 \(10\) 元的硬幣的數量範圍小於 \(3\)。
當使用大於等於 \(3\) 個 \(10\) 元硬幣。
則可以用 \(2\) 個面值為 \(15\) 的硬幣代替。
5:面值為 \(15\) 的硬幣。
剩下的數目都有面值為 \(15\) 的硬幣承擔就好了。
時間複雜度
因為前面的數值都很少,所以時間複雜度也十分小。
程式碼
#include <bits/stdc++.h>
using namespace std;
int n,t,ans;
int main() {
cin>>t;
while(t--){
cin>>n;
ans=1000000000;
for(int i=0;i<3;i++)
for(int j=0;j<2;j++)
for(int k=0;k<5;k++)
for(int m=0;m<3;m++){
int y=i*1+j*3+k*6+m*10;
if(y>n)continue;
if((n-y)%15==0){
ans=min(ans,i+j+k+m+(n-y)/15);
}
}
cout<<ans<<endl;
}
}