hdu个人赛6—1009

来源:互联网 发布:多多淘宝客返利网源码 编辑:程序博客网 时间:2024/06/01 22:56

小P玩游戏2

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 92    Accepted Submission(s): 13


Problem Description
小p最近迷上了一个游戏,但他在玩游戏的时候遇到了一个问题。
小P控制n个角色,标号为1到n,小P有K个怪物可以分配给这n个角色击杀,一个怪物只能分配给一个 角色,并且必须要分配给一个角色。
对于第i(1 <= i <= n)个角色,如果没有分配到一个怪物,那么它就会获得经验ci,如果分配到了t(t>=1)个怪物,那么它会获得经验ai+tbi
小P要把K个怪物分配给这n个角色,问所有角色获得的经验总和最多是多少。
 

Input
输入第一行一个整数T,表示有T组数据。
对于每组数据,第一行两个正整数n和K。
接下来n行,每行三个整数ai,bi,ci。。
1 <= T <= 50 
1 <= n,K <= 100000
1 <= ai,bi,ci <= 100000
 

Output
对于每组数据,输出一个整数表示答案。
 

Sample Input
22 24 1 11 3 32 24 1 11 3 4
 

Sample Output
910
 

【分析】

首先要发现一点...就是最多只有一个人可能被分到多个怪兽,因为如果某个人会分到两只怪兽,那么说明他的b收益要比所有分不到怪兽的人高,但是直接去找b最高的人肯定是有问题的,所以只要确定这个分到多只怪兽的人是谁就可以了,数据不大,枚举一遍就好了,相当于所有a+b-c小于当前第i个人的b值的人都不分怪兽,都给这个人。

也就是说在找到pos位置a[pos]+b[pos]-c[pos]<=b[i]时,左边c求和,右边a+b求和,当前人获得右边分完后的所有怪兽即可,

另外需要注意:

1.找到的pos位置有可能>i,那就要-c[i]+a[i]...

2.存在右边人数>怪兽数量的情况,所以考虑排序的时候从大到小排序,二分边界设置为min(k-1,n)因为第i个人需要分到怪兽,所以是k-1

//一开始正过来排,倒过来求前缀和,wa到爆炸....大概是我太菜了...不然思路是对的...代码写错了而已

【代码】

#include <cstdio>#include <algorithm>#include <cstring>#include <algorithm> using namespace std;struct xx{    long long a,b,c,dis;}f[100010];long long aa[100010];long long bb[100010];long long cc[100010];long long dd[100010];long long sum[100010];long long summ[100010];bool cmp(const xx&x,const xx&y){    return x.dis>y.dis;}int main(){    int pp;scanf("%d",&pp);    while (pp--)    {        int n,m;scanf("%d%d",&n,&m);        for (int i=1;i<=n;i++)         {            scanf("%lld%lld%lld",&f[i].a,&f[i].b,&f[i].c);            f[i].dis=f[i].a+f[i].b-f[i].c;        }        sort(f+1,f+1+n,cmp);        sum[0]=summ[0]=0;        long long ans=-1;        for (int i=1;i<=n;i++) sum[i]=sum[i-1]+f[i].dis,summ[i]=summ[i-1]+f[i].c;        for (int i=1;i<=n;i++)        {            int l=1,r=min(m-1,n);            while (l<=r)            {                int mid=(l+r)>>1;                if (f[mid].dis>f[i].b) l=mid+1;                else r=mid-1;            }            if (r>=i)                 ans=max(ans,(long long)sum[r]+(m-r)*f[i].b);            else ans=max(ans,(long long)sum[r]+f[i].dis+(m-r-1)*f[i].b);        }        printf("%lld\n",ans+summ[n]);    }    return 0; }



原创粉丝点击