贪心
先把高低电压各存在一个数组并排序
题目思路很简单。 就是先 贪心得到 最少的机器数num
然后分2种情况
1:num<= 所有低电压机器数量 此时 先假设全部低电压被选了
然后 根据 if (当前cap之和是否>= m) 来贪心 ( 不断比较"已选"的最小cap的低电压机器 和较大cap的高电压机器) (都已排序)
2: num>总低电压机器数量(a)
此时 先假设全部低电压机器被选了,并且再选num-a步 较大cap的高电压(已排序)
然后也是 根据 if (当前cap之和是否>= m) 来贪心 ( 不断比较"已选"的最小cap的低电压机器 和”未选“的较大cap的高电压机器) (都已排序)
代码写得比较长。。。乱
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <set>
#include <vector>
using namespace std;
struct ren
{
__int64 ca;
int v;
__int64 code;
};
ren tm[100000*2+5]; //所有机器 //升序
ren nm1[100000*2+5]; //保存低电压code 升序
ren nm2[100000*2+5]; //保存高电压code 升序
__int64 ans[100000*2+5]; //记录选过了的code
__int64 vis[100000*2+5]; //标记要删除的code
int cmp(ren a,ren b)
{
if (a.ca!=b.ca)
return a.ca>b.ca;
else
{
return a.v>b.v;
}
}
int main()
{
__int64 i,j;
__int64 n,m,cop_m;
scanf("%I64d %I64d",&n,&m);
cop_m=m;
for (i=1;i<=n;i++)
{
scanf("%I64d %d",&tm[i].ca,&tm[i].v);
tm[i].code=i;
}
sort(tm+1,tm+1+n,cmp);
__int64 ok1=0;
__int64 ok3=0;
__int64 ok2=0;
__int64 star=0;
for (i=1;i<=n;i++)
{
if (tm[i].v==1)
{
nm1[++ok1].ca=tm[i].ca;
nm1[ok1].code=tm[i].code;
}
else
{
nm2[++ok2].ca=tm[i].ca;
nm2[ok2].code=tm[i].code;
}
}
__int64 num=0;
for (i=1;i<=n;i++)
{
if (m<=0) break;
m-=tm[i].ca;
num++;
}
m=cop_m;
__int64 max_low=0; //最小低电压机器数
if (num<=ok1) // 最小机器数小于等于 低电压机器数
{
for(i=1;i<=num;i++)
{
star+=nm1[i].ca;
ans[++ok3]=nm1[i].code;
}
max_low=num; //此情况下 假设先全部选低电压
__int64 it;
for ( i=num,j=1;j<=ok2 &&i>=1;)
{
if (star>=m) break;
star=star-nm1[i].ca+nm2[j].ca;
// sort(ans+1,ans+1+ok3);
// it= lower_bound(ans+1,ans+1+ok3,nm1[i].code)-&ans[1]+1;
// ans[it]=0;
vis[nm1[i].code]=-1; //删除该编号
ans[++ok3]=nm2[j].code;
max_low--;
i--;
j++;
}
}
else // 最小机器数大于 低电压机器数
{
for(i=1;i<=ok1;i++) //此情况下 假设先全部选低电压 再从最大cap值的高电压机器凑够num个
{
star+=nm1[i].ca;
ans[++ok3]=nm1[i].code;
}
for(i=1;i<=num-ok1;i++)
{
star+=nm2[i].ca;
ans[++ok3]=nm2[i].code;
}
max_low=ok1; //最小低电压机器数为ok1个(全部低电压机器)
__int64 it;
for ( i=ok1,j=num-ok1+1;j<=ok2 &&i>=1;)
{
if (star>=m) break;
star=star-nm1[i].ca+nm2[j].ca;
// sort(ans+1,ans+1+ok3);
// it= lower_bound(ans+1,ans+1+ok3,nm1[i].code)-&ans[1]+1;
// ans[it]=0;
vis[nm1[i].code]=-1; //删除该编号
ans[++ok3]=nm2[j].code;
max_low--;
i--;
j++;
}
}
int line=0;
printf("%I64d %I64d\n",num,max_low);
for (i=1;i<=ok3;i++)
{
if ( vis[ans[i]] !=-1 )
{
if (line!=0) printf(" ");
printf("%I64d",ans[i]);
line=1;
}
}
printf("\n");
return 0;
}