嘿嘿,今天终于想起来这题了,写一写。
其实就是分组背包,分组背包的好处就在于分了组之后只需要考虑到当前组选了多少种,而不用记录每一种物品有没有选过。
那么用 d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k]表示第 i i i组,已经选了 j j j种物品,奖励为十分之 k k k的情况下最大能获得的分数。答案就是 m a x ( d p [ t o t ] [ j ] [ k ] ∗ ( 10 + k ) / 10 ) max(dp[tot][j][k] *(10 + k) / 10) max(dp[tot][j][k]∗(10+k)/10),其中 t o t tot tot是组数。
转移就十分显然了,甚至不需要开滚动空间。
C
o
d
e
:
Code :
Code:
#include<set>
#include<map>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<string>
#include<vector>
#include<random>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#define endl "\n"
#define fi first
#define se second
#define db double
#define gcd __gcd
#define pb push_back
#define mp make_pair
#define lowbit(x) (x & (-x))
#define PII pair<int, int>
#define all(x) x.begin(), x.end()
#define debug(x) cout << #x << " = " << x << endl
#define rep(i, a, b) for(__typeof(b) i = a; i <= (b); i++)
#define Rep(i, a, b) for(__typeof(a) i = a; i >= (b); i--)
#define FAST ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
template<class T> inline T qmin(T a, T b) { return a < b ? a : b; }
template<class T> inline T qmax(T a, T b) { return a > b ? a : b; }
typedef long long ll;
typedef unsigned long long ull;
const db eps = 1e-9;
const db PI = acos(-1);
const int inf = 0x3f3f3f3f;
const int mod = (int)1e9 + 7;
const int maxn = (int)1e5 + 5;//remember to modify it, No RE or MLE
const ll INF = 0x3f3f3f3f3f3f3f3f;
using namespace std;
struct node{
string name;
int val, add;
friend bool operator < (node p, node q){
return p.name < q.name;
}
}a[maxn];
int dp[maxn][6][16];
string color[maxn], bonus_name[10], bonus_color;
vector<node> G[maxn];
int n, tot;
int main()
{
FAST;
int T; cin >> T;
while(T--){
cin >> n;
rep(i, 1, n) cin >> a[i].name >> color[i] >> a[i].val, a[i].add = 0, G[i].clear();
rep(i, 1, 5) cin >> bonus_name[i];
cin >> bonus_color;
rep(i, 1, n){
rep(j, 1, 5){
if(a[i].name == bonus_name[j]) a[i].add += 1;
}
if(color[i] == bonus_color) a[i].add += 2;
}
sort(a + 1, a + n + 1);
tot = 0;
rep(i, 1, n){
if(a[i].name != a[i-1].name) tot++;
G[tot].pb(a[i]);
}
memset(dp, -1, sizeof dp);
dp[0][0][0] = 0;
rep(i, 1, tot){
int len = G[i].size();
rep(j, 0, 5){
rep(k, 0, 15) dp[i][j][k] = dp[i-1][j][k];
}
rep(l, 0, len - 1){
rep(j, 1, 5){
rep(k, G[i][l].add, 15){
if(dp[i-1][j-1][k-G[i][l].add] != -1) dp[i][j][k] = qmax(dp[i][j][k], dp[i-1][j-1][k-G[i][l].add] + G[i][l].val);
}
}
}
}
int ans = 0;
rep(j, 0, 5) rep(k, 0, 15) {
ans = qmax(ans, dp[tot][j][k] * (10 + k) / 10);
}
cout << ans << endl;
}
return 0;
}
Over.