单点时限: 2.0 sec
内存限制: 256 MB
ultmaster 男神和小迷妹们玩起了捉迷藏的游戏。
小迷妹们都希望自己被 ultmaster 男神发现,因此她们都把自己位置告诉了 ultmaster 男神,因此 ultmaster 男神知道了自己去找每个小迷妹所要花的时间。
已知发现第 i 小迷妹得到的分数为 ai⋅tr(tr 为游戏剩余时间)。ultmaster 想知道他最多能拿多少分。
输入格式
第一行两个整数 n,T (1≤n≤105,1≤T≤300) 分别表示小迷妹数量,游戏总时间。
接下去 n 行,每行两个整数 ai,ti (1≤ai≤100,1≤ti≤300) 分别表示发现小迷妹的分数以及 ultmaster 男神发现小迷妹所需时间。
输出格式
一个整数,表示 ultmaster 在游戏中最多拿多少分。
样例
input
2 10
2 5
1 6
output
10
input
3 5
5 4
1 1
10 6
output
5
提示
样例一:找到小迷妹一,找到后得分 2×(10−5)=10 分。
样例二:找到小迷妹一,找到后得分 5×(5−4)=5 分,之后再找到小迷妹二得分也是 0,所以最高得分 5 分。
/*
尽可能先找到性价比高的小迷妹,
所以按性价比排个序,然后就是个裸的背包。
假设两个小迷妹分别含有a1,t1和a2,t2.
假设她们性价比相同也就是说先找哪个都一样,
设找之前的时间为t,可以得到等式
(t-t1)a1+(t-t1-t2)a2=(t-t2)a2+(t-t1-t2)a1;化
简得到:a1t2=a2t1,发现区分迷妹价值和时间t无关,
*/
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
struct g
{
int a;
int t;
}G[100000];
bool cmp(g a,g b)
{
return a.a*b.t>b.a*a.t;
}
int main()
{
int n,t;
cin>>n>>t;
long long dp[t+1];
memset(dp,0,sizeof(dp));
for(int i = 0; i < n; i++)
{
cin>>G[i].a>>G[i].t;
}
sort(G,G+n,cmp);
long long ans=0;
for(int i = 0; i < n; i++)
{
for(int j=t;j>=G[i].t;j--)
{
dp[j]=max(dp[j],dp[j-G[i].t]+(t-j)*G[i].a);
ans=max(ans,dp[j]);
}
}
cout<<ans;
return 0;
}