这个题,有一个易错点就是要根据优先级排序。
这道题一看就是个01背包,但是问题是01背包问题是按照给定的数组顺序进行排序的,也就是说,选或者不选,你的顺序都是确定的,不能变:
例如
1 2 3 4 5
按照01背包问题可以选择1 2 5
但是答案是2 1 5(因为不同的时间做题得分不一样codeforces一大特点)
因此要先按照优先级进行有针对性地排序:
如何实现这个操作呢?
现在给你两个数据:
1:最高得分a1,每分钟减去的得分b1,和做这道题要用的时间c1
2:a2,b2,c2同理
那么先做1我的得分就是
a
1
+
a
2
−
c
1
∗
b
1
−
b
2
∗
(
c
1
+
c
2
)
a1+a2-c1*b1-b2*(c1+c2)
a1+a2−c1∗b1−b2∗(c1+c2)
那么先做2我的得分就是
a
1
+
a
2
−
c
2
∗
b
2
−
b
1
∗
(
c
1
+
c
2
)
a1+a2-c2*b2-b1*(c1+c2)
a1+a2−c2∗b2−b1∗(c1+c2)
根据这个值来进行优先级排序。
下面是AC代码
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
//ll a[210210];
//ll b[210210];
//ll c[210210];
struct node{
ll a,b,c;
}s[210210];
ll dp[210210];
bool cmp(node x,node y){
return x.b>y.b;
}
int main(){
ll n,t;
cin>>n>>t;
for(ll i=1;i<=n;i++)cin>>s[i].a;
for(ll i=1;i<=n;i++)cin>>s[i].b;
for(ll i=1;i<=n;i++)cin>>s[i].c;
sort(s+1,s+1+n,cmp);
for(ll i=1;i<=n;i++){
for(ll j=t;j>=s[i].c;j--){
// cout<<s[i].a<<' '<<j*s[i].b<<endl;
// cout<<"dp-->"<< s[i].a-(j*s[i].b)<<endl;
dp[j]=max(dp[j],dp[j-s[i].c]+s[i].a-(j*s[i].b));
// cout<<dp[j]<<endl;
}
}
ll ans=0;
for(ll i=0;i<=t;i++)ans=max(ans,dp[i]);
cout<<ans<<endl;
}