贪心
先把高低电压各存在一个数组并排序
题目思路很简单。 就是先 贪心得到 最少的机器数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; }