Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1323 Accepted Submission(s): 565 Problem Description The SDOI in 2045 is far from what it was been 30 years ago. Each competition has t minutes and n problems.
Input There is an positive integer T(T≤10) in the first line for the number of testcases.(the number of testcases with n>200 is no more than 5 )
Output For each testcase output a line for an integer, for the highest mark dxy will get in this competition.
Sample Input 1 4 10 110 5 9 30 2 1 80 4 8 50 3 2
Sample Output 88
Source
Recommend hujie |
题目大意:类似于比赛的赛制,看其中的得分,给你N道题,M个时间,花费时间做题的同时还要接受花费时间多少给出的减分,做一道题得A分,这一道题一个时间减少B分,做出来这个题需要C个时间。
思路:
现在有A1,B1,C1和A2,B2,C2这两道题,如果先做1再做2的得分是A1-B1*C1+A2-B2*(C1+C2),如果先做2在做1的得分是A2-B2*C2+A1-B1*(C1+C2),令先做1再做2的得分更高些,那么有A1-B1*C1+A2-B2*(C1+C2) >= A2-B2*C2+A1-B1*(C1+C2),解得B1*C2>=B2*C1
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define maxn 3500
using namespace std;
int dp[maxn];
int n,m;
struct Data
{
int a,b,c;
Data() {}
Data(int d,int e,int f):a(d),b(e),c(f){}
bool operator <(const Data &ags) const
{
return b*ags.c>ags.b*c;
}
}D[maxn];
int main()
{
int t;cin>>t;
while(t--)
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>D[i].a>>D[i].b>>D[i].c;
}
sort(D+1,D+n+1);
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
for(int j=m;j>=D[i].c;j--)
dp[j]=max(dp[j],dp[j-D[i].c]+D[i].a-D[i].b*j);
int ans=0;
for(int j=0;j<=m;j++)
ans=max(ans,dp[j]);
cout<<ans<<endl;
}
}