洛谷-纪念品分组(1094)
问题分析:
根据问题描述,得出最优解应该满足分组尽可能少。此外要求,每组至多两件物品且价值尽量均匀,而且还不能超过规定价格。
找出问题所在,解便不难得出。倘若价值最大的和价值最小的都没有超过规定价格,则次小和次大两两组合也能满足要求。如若不能,则价值最大的便自己单独一组,最小的和次大的组合再次比较,看是否满足要求。
代码示例:
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
int w, n;
cin >> w >> n;
int value[n];
for(int i = 0; i < n; i++){
cin >> value[i];
}
sort(value, value+n);
int i =0, j = n-1, count = 0;
while(i <= j){
if(value[i] + value[j] <= w){//寻找价值较大的同价值较小的组合
j--;
i++;
} else {//价值较大的单独放置
j--;
}
count++;
}
cout << count;
return 0;
}
上述代码,对程序执行贡献最大的是一次排序,需要O(nlogn)的时间,因此时间复杂度为O(nlogn)。
洛谷-合并果子(1090)
最大整数
问题分析:
典型的贪心求解问题,问题的最优解要求得到的整数最大。因此每次局部求解过程中,都应该找到序列中的最大值。这里的局部最大值,并非真正意义上的最大值,而是应该选择每个数的第1、2、3……位上的数值尽可能大的数。例如123和72,在实际意义上,123>72,但是本题,72的首位是7,123首位是1,显然7>1,因此应首选72,而不是123。
代码示例:
#include<iostream>
#include<algorithm>
using namespace std;
bool cmp(string a, string b){
if(a + b > b + a) return 1;
else return 0;
}
int main(){
int n;
cin >> n;
string ars[n];
string res = "";
for(int i = 0; i < n; i++)
cin >> ars[i];
sort(ars, ars + n, cmp);
for(int i = 0; i < n; i++)
res += ars[i];
cout << res;
return 0;
}