》》》算法竞赛
/**
* @file
* @author jUicE_g2R(qq:3406291309)————彬(bin-必应)
* 一个某双流一大学通信与信息专业大二在读
*
* @brief 一直在算法竞赛学习的路上
*
* @copyright 2023.8
* @COPYRIGHT 原创技术笔记:转载需获得博主本人同意,且需标明转载源
*
* @language C++
* @Version 1.0还在学习中
*/
11-贪心法和拟阵
贪心法求找零问题(最少硬币问题)
核心:局部最优
作为算法的贪心,就是把整个问题分成多个步骤,在每个步骤都选取当前步骤的最优方案,直到所有步骤结束
每一步不考虑对后续的影响,后续步骤也不改变前面步骤原有的选择
精简写法:
#include<bits/stdc++.h>
using namespace std;
const int cot=3;
int coins[]={1,5,10};
int main(void){
int money; cin>>money;
int ans[cot]={0};
for(int i=cot-1;i>=0;i--){
ans[i]=money/coins[i];//从最大的开始
money-=ans[i]*coins[i];
}
for(int i=0;i<cot;i++)
cout<<coins[i]<<"yuan: "<<ans[i]<<endl;
return 0;
}
标准写法:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(void){
int amount; cin>>amount;
vector<int> changes={10,5,1};//仅需该面值
std::vector<int> cot(changes.size(),0);//面额降序排列,每种面额的张数
sort(changes.rbegin(), changes.rend());//对硬币面额进行降序排序
for(int i=0;i<changes.size();i++){//从最大的
while(amount>=changes[i]){
++cot[i];
amount-=changes[i];
}
}
if(amount!=0)//如果无法凑成金额,则返回空数组
cot.clear();//贪心的核心
for(int i=0;i<changes.size();i++)
cout<< changes[i] << ":" << cot[i] <<endl;
return 0;
}