題目描述
小PP最近迷上了一個遊戲,但他在玩遊戲的時候遇到了一個問題。
小PP控制nn 個角色,标号為11到nn,小PP有KK個怪物可以配置設定給這nn個角色擊殺,一個怪物隻能配置設定給一個角色,并且必須要配置設定給一個角色。
對于第 i\,(1 \leq i \leq n)i(1≤i≤n)個角色,如果沒有配置設定到一個怪物,那麼它就會獲得經驗c_ici,如果配置設定到了t\,(t \geq 1)t(t≥1)個怪物,那麼它會獲得經驗a_i + t b_iai+tbi。
小PP要把KK個怪物配置設定給這nn個角色,問所有角色獲得的經驗總和最多是多少。
輸入格式
輸入第一行一個整數TT,表示有TT組資料。
對于每組資料,第一行兩個正整數nn和KK。
接下來nn行,每行三個整數a_i,b_i,c_iai,bi,ci。
1 \leq T \leq 501≤T≤50
1 \leq n, K \leq 1000001≤n,K≤100000
1 \leq a_i, b_i, c_i \leq 1000001≤ai,bi,ci≤100000
輸出格式
對于每組資料,輸出一個整數表示答案。
樣例資料
輸入
2
2 2
4 1 1
1 3 3
2 2
4 1 1
1 3 4
輸出
9
10
備注
思路:(參考題解和師兄的代碼)最佳配置設定的情況是這樣的,配置設定到>1隻怪的人一定<=1個,而這個人又是已配置設定到怪裡面的人b值最大的,其餘未配置設定到怪的人ai+bi-ci <= b,那麼這個人是誰無法确定,是以枚舉一下這個人就行。
# include <bits/stdc++.h>
# define ll long long
using namespace std;
const int maxn = 1e5;
struct node
{
int a, b, c, d;
}m[maxn+3];
bool cmp(node x, node y)
{
return x.d > y.d;
}
ll sum[maxn+3];
int main()
{
int t, n, k;
scanf("%d",&t);
while(t--)
{
ll tot = 0;
scanf("%d%d",&n,&k);
for(int i=1; i<=n; ++i)
{
scanf("%d%d%d",&m[i].a, &m[i].b, &m[i].c);
m[i].d = m[i].a + m[i].b - m[i].c;
}
sort(m+1, m+1+n, cmp);
for(int i=1; i<=n; ++i)
tot += m[i].c, sum[i] = sum[i-1] + m[i].d;
ll ans = 0;
for(int i=1; i<=n; ++i)
{
int l = 1, r = min(n,k-1);//k-1為上限是因為有一個怪已經配置設定給i了。
while(l<=r)
{
int mid = l+r>>1;
if(m[mid].d > m[i].b)
l = mid+1;
else
r = mid-1;
}
if(r < i) ans = max(ans, (ll)tot + sum[r] + m[i].d + (ll)(k-r-1)*m[i].b);
else ans = max(ans, (ll)tot + sum[r] + (ll)(k-r)*m[i].b);//這裡比較巧妙,當r==k-1時這樣處理貌似有bug,因為最佳可能是每個人分一個怪,但這裡剩下的一個怪強制分給i了,然而枚舉到最後一個人時又正确了。
}
printf("%lld\n",ans);
}
return 0;
}