Test instructions
[Topic link] This How to send a link ah .....
There \ (n\) Zhang Fuka in a queue, each spell card has two attributes, Rank \ (li\) and damage \ (di\).
You can do any operation, each one of the following:
Move the team's first spell card to the end of the team.
Use the team's first spell card to damage the enemy ( d_i\) and discard the l_i\ Zhang Fuka (including the spell card you used). If the queue is insufficient \ (l_i\) Zhang Fuka Then you cannot use it.
The maximum value of the sum of the resulting damage is calculated.
\ (1<=n<=50, 1<=li<=50, 1<=di<=10000\)
Sol
Conclusion: If the chosen card satisfies \ (\sum l_i <= n\), then there is always a plan to play these cards
A backpack, van.
That's a pretty obvious conclusion, but it's not really that good in the exam room.
A simple proof:
The problem in the sequence is more difficult to handle, we put them on the ring, so as to eliminate the effect of operation 1
Obviously, the selected card must exist adjacent to the two (I-j > L_i\), that is, one of the release skills will not kill the other (otherwise must \ (>n\))
We used this card, so the problem turned into the same sub-problem.
#include<bits/stdc++.h>using namespace std;inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f;}int f[100];class SpellCards{public: int maxDamage(vector<int> l, vector<int> d) { int N = l.size(); for(int i = 0; i < N; i++) for(int j = N; j >= l[i]; j--) f[j] = max(f[j], f[j - l[i]] + d[i]); return *max_element(f + 1, f + N + 1); }};int main() { int N = read(); vector<int> l, d; for(int i = 1; i <= N; i++) l.push_back(read()); for(int i = 1; i <= N; i++) d.push_back(read()); cout << SpellCards().maxDamage(l, d);}/*71 2 2 3 1 4 2113 253 523 941 250 534 454*/
Topcoder SRM 563 Div1 spellcards