题目描述
牛牛今天逛商店,看到商店里摆着一些很漂亮的数字,牛牛非常喜欢,想买一些数字带回家。
数字一共有九种类型,分别是1-9这九个数字,每个数字的价钱都不一样,而且每个数字的货源都非常充足。
牛牛是个完美主义者,他希望用自己的能够承受的价格,从这些数字里面购买,并且凑到最大的数字带回家。
示例1
输入
复制
5,[5,4,3,2,1,2,3,4,5]
输出
复制
"55555"
说明
第5个数字只需要花费1,所以买5个第5个数字可以凑到最大值55555。
示例2
输入
复制
5,[9,11,11,12,5,8,3,4,16]
输出
复制
"8"
说明
购买1个第8个数字,可以凑到最大值为88。
贪心思路:
需要尽可能凑出更多的数字,组成更大的位数,那么假设先全部买最便宜的那个数字
最便宜的数字可能有多个,需要选择靠后的数字(更大),最终的位数一定是确定的,(最多买多少个数字)
可能有剩余的钱,那么拿出一个 最便宜数字单价+剩余的钱 置换一个更大的数 放在开头,数字将更大
置换哪一个数字?,一定是能置换最大就最大,9=>1 从后往前扫描。
置换完成以后可能还有剩余,迭代不断置换(置换的标准是 ①置换后的数字更大 ②若某一个没有置换出更大的,那么结束循环)
那些置换后的数字,就不断放在开头(由于总是从最大的数字扫描,因此ans+=c 即可)
易错点:
最多置换次数 不超过最终的最大位数
class Solution {
public:
/**
* 得到牛牛能够凑到的最大的数字
* @param n int整型 牛牛能够承受的价格
* @param a int整型vector 1-9这九个数字的价格数组
* @return string字符串
*/
string solve(int n, vector<int>& a) {
// write code here
int len=a.size();
int min_price=INT_MAX;
int index=-1;//最低价格是哪个数字
for(int i=0;i<len;i++)
{
if(a[i]<=min_price)
{
min_price=a[i];//最低的单价
index=i+1;
}
}
int res_len=n/min_price;//最后返回串的长度(一定是总价格 除以最低单价)
if(res_len==0)
return string("-1");
int remain=n-res_len*min_price;//假如全部购买最低价的数字 剩余的钱
string ans;
//每次试图将(一份最低价+剩余的钱 去置换一个更大的数字 如果都没有退出)
int count=0;
while(remain>0 && count<res_len)
{
int i;
for(i=len-1;i>index-1;i--) //从9=》1迭代 因为能换最大就换最大
{
if(a[i]<=remain+min_price ) //
{
ans+='0'+(i+1);//最终结果头部插入这个最大的数
remain=remain+min_price-a[i];//剩余的钱更少
break;//本轮判断结束
}
}
if(i==index-1) //若在一次置换中,没有一个能置换 那么退出
break;
count++;
}
for(int i=0;i<res_len-count;i++) //补上 那些最低价买入的数字(在最后)
ans+='0'+index;
return ans;
}
};