题意翻译
超市进行优惠活动,顾客如果在一架购物车中放上一个凳子,他就可以半价买掉这架购物车里最便宜的商品。
每一辆购物车的容量是无限的,但一个购物车里只能有一件商品半价。
现在要用
架购物车装要买的
件商品,里面有一些是凳子。他希望用最少的钱来买这些东西。
输入格式
第一行两个整数、
;
第行至第
行,每行两个整数
,
。
其中表示商品
的价格,
表示商品
的类型(
表示它是凳子,
表示它不是凳子)
输出格式
第一行输出一个一位小数,表示折扣之后最少需要付的价格。
接下来的行,每行开头输出一个整数
,表示购物车
中商品的数量。
后面跟着$$,分别表示商品的编号。
方案可能有很多,输出其中一种即可。购物车和商品的输出顺序不作要求。
Input & Output 's examples
Input 's eg 1
3 2 2 1 3 2 3 1
Output 's eg 1
5.5 2 1 2 1 3
Input 's eg 2
4 3 4 1 1 2 2 2 3 2
Output 's eg 2
8.0 1 1 2 4 2 1 3
样例解释
在样例中,购物车有
架,其中一架装商品
(凳子)和
(其他),另一架装商品
(凳子)。
这样安排便可以使价格最低。
数据范围和约定
对于的数据,
分析
又是一道贪心好题
我们先只考虑单个凳子的情况,显然,一个凳子只能让自己或者一个价格比自己低的东西半价。
而题目中让我们最小化价格,即让省下的钱最多。因此,我们尽量多的让一个凳子单独在一个购物车中。
显然,这个最大值为。因为你还要留出一辆购物车来存储其他的物品。
但这还不够。如果凳子的数量小于的话,我们就把所有的凳子半价,然后原价买下其他商品即可
最后别忘了保留一位小数。
剩下的见代码注释。
Code[Accepted]
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<cstdlib>
#include<cctype>
#include<cmath>
#define ll long long
#define I inline
#define N 100001
using namespace std;
int n , k;
struct Node{
long double val; //题目要求输出一位小数,因此要开long double
int num;
int str;
}node[N];
int cnt;
long double ans_num;
bool cmp(Node a , Node b){
if(a.str == b.str == 1){ //如果他们都是凳子,就把价值大的放在前边。
return a.val > b.val;
}
else{ //否则,将凳子放在前边
return a.str < b.str;
}
}
pair<int , int > ans[N];
int main(){
cin >> n >> k;
for(int i = 1; i <= n; i ++){
cin >> node[i].val >> node[i].str;
node[i].val *= 1.0;
node[i].num = i;
if(node[i].str == 1){
cnt ++; //记录凳子的数量
}
}
sort(node + 1 , node + 1 + n , cmp);
if(cnt > k - 1){ //分类讨论,当凳子数量大于购物车数量-1时
for(int i = 1; i <= k - 1; i ++){
node[i].val /= 2;
ans_num += node[i].val;
ans[i] = make_pair(1 , node[i].num);
}
long double minn = 0x3f3f3f3f;
for(int i = k; i <= n; i ++){
ans_num += node[i].val;
if(node[i].val < minn){
minn = node[i].val;
}
}
ans_num -= minn;
ans_num += minn / 2;
cout << fixed << setprecision(1) << ans_num << "\n";
for(int i = 1; i <= k - 1; i ++){
cout << ans[i].first << " " << ans[i].second << "\n";
}
cout << n - k + 1 << " ";
for(int i = k; i <= n; i ++){
cout << node[i].num << " ";
}
puts("");
}
else if(cnt == k - 1){ //当凳子数量等于购物车数量-1时
for(int i = 1; i <= k - 1; i ++){
node[i].val /= 2;
ans_num += node[i].val;
ans[i] = make_pair(1 , node[i].num);
}
for(int i = k; i <= n; i ++){
ans_num += node[i].val;
}
cout << fixed << setprecision(1) << ans_num << "\n";
for(int i = 1; i <= k - 1; i ++){
cout << ans[i].first << " " << ans[i].second << "\n";
}
cout << n - k + 1 << " ";
for(int i = k; i <= n; i ++){
cout << node[i].num << " ";
}
puts("");
}
else{ //当凳子数量小于购物车数量-1时
for(int i = 1; i <= cnt; i ++){
node[i].val /= 2;
ans_num += node[i].val;
ans[i] = make_pair(1 , node[i].num);
}
for(int i = cnt + 1; i <= n; i ++){
ans_num += node[i].val;
}
cout << fixed << setprecision(1) << ans_num << "\n";
for(int i = 1; i <= cnt; i ++){
cout << ans[i].first << " " << ans[i].second << "\n";
}
for(int i = cnt + 1; i <= k - 1; i ++){
cout << 1 << " " << node[i].num << "\n";
}
cout << n - k + 1 << " ";
for(int i = k; i <= n; i ++){
cout << node[i].num << " ";
}
puts("");
}
return 0;
} 
京公网安备 11010502036488号