題目簡述node
給定比賽時間T和n個題目,你能夠在任意時間提交題目,每一個題目有一個初始分數maxPoints[i],每一個單位時間題目的分數將會減小pointsPerMinute[i],即若是在時間t解決了第i個題目,那麼得到的分數爲maxPoints[i] - t * pointsPerMinute[i],另外作每一個題目須要requiredTime[i]的時間,求可以得到的最大分數是多少?ui
題解spa
因爲問題解決的前後,得到的分數是不同的,由於咱們首先得肯定作題的選擇順序,根據相鄰交換法,對於問題a和問題b,若是requiredTime[b]*pointsPerMinute[a]>requiredTime[a]*pointsPerMinute[b],先解決a再解決b得到的分數會比先b後a多,因此咱們能夠先根據這個條件對題目進行排序,以後就是01揹包問題了code
代碼:blog
1 struct node 2 { 3 int mp, pp, rt; 4 }; 5 node a[55]; 6 int dp[100005]; 7 bool cmp(node a, node b) 8 { 9 return (LL)b.rt * a.pp > (LL)a.rt * b.pp; 10 } 11 class TheProgrammingContestDivOne 12 { 13 public: 14 LL find(int T, vector <int> maxPoints, vector <int> pointsPerMinute, vector <int> requiredTime) 15 { 16 int n = maxPoints.size(); 17 for (int i = 0; i < n; i++) 18 { 19 a[i + 1].mp = maxPoints[i]; 20 a[i + 1].pp = pointsPerMinute[i]; 21 a[i + 1].rt = requiredTime[i]; 22 } 23 sort(a + 1, a + n + 1, cmp); 24 memset(dp, 0, sizeof(dp)); 25 for (int i = 1; i <= n; i++) 26 for (int j = T; j >= a[i].rt; j--) 27 if (a[i].mp - (LL)a[i].pp * j >=0) 28 dp[j] = max(dp[j], dp[j - a[i].rt] + a[i].mp - a[i].pp * j); 29 int ans = 0; 30 for (int i = 0; i <= T; i++) ans = max(ans, dp[i]); 31 return ans; 32 } 33 };