最优得分 score

Solution:

  一道很典型的dp题目,

  对于 20% 的数据(Bi=0),直接使用01背包即可。

  对于 100% 的数据,我们需要进行分析,当我们对 …a,b… 和 …b,a… (…表示的是相同的序列)进行求最大值时,我们只需对不同的序列(也就是a,b)的不同排列方式求最大值,当a消耗ta秒,每秒消耗x,b消耗tb秒,每秒消耗y时,我们得到这两种不同排列方式的不同消耗分别为 [ta*x+(ta+tb)*y]① 和 [tb*y+(ta+tb)*x]②. 对①②两式做差,得到 [ta*y-ta*x]③,令③<0得到ta*y<tb*x;于是我们便以④为compare函数进行排序,再进行01背包求解即可。

 

 1 #include<algorithm>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 const int maxm=3e3+5;
 6 int f[maxm];
 7 struct cp{
 8     int s,x,t;
 9 }e[maxm];
10 bool cmp(cp a,cp b){return a.t*b.x<a.x*b.t;}
11 inline int max(int a,int b){return a>b?a:b;}
12 inline void init(){
13     memset(e,0,sizeof e);
14     memset(f,0,sizeof f);
15 }
16 inline int read(){
17     char ch=getchar();
18     int x=0,f=1;
19     while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
20     while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
21     return x*f;
22 }
23 int main(){
24 /*    freopen("score.in","r",stdin);
25     freopen("score.out","w",stdout);*/
26     int T=read(),n,t,ans=0;
27     while(T--){
28         init();
29         ans=0;
30         n=read(),t=read();
31         for(int i=1;i<=n;i++) e[i].s=read(),e[i].x=read(),e[i].t=read();
32         sort(e+1,e+n+1,cmp);
33         for(int i=1;i<=n;i++)
34             for(int j=t;j>=e[i].t;j--)
35                 f[j]=max(f[j],f[j-e[i].t]+e[i].s-j*e[i].x);
36         for(int i=1;i<=t;i++) ans=max(ans,f[i]);
37 /*        for(int i=1;i<=n;i++){
38             for(int j=1;j<=t;j++) f[i][j]=f[i-1][j];
39             for(int j=t;j>=e[i].t;j--)
40                 f[i][j]=max(f[i-1][j],f[i-1][j-e[i].t]+e[i].s-e[i].x*j);
41         }*/
42         for(int i=1;i<=t;i++) ans=max(ans,f[i]);
43         printf("%d\n",ans);
44     }
45     return 0;
46 }
47 /*
48 1
49 4 10
50 110 5 9
51 30 2 1
52 80 4 8
53 50 3 2
54 Ans: 88
55 */
View Code

 

posted @ 2018-07-12 18:08  Rising_Date  阅读(176)  评论(0编辑  收藏  举报