文章目录
icpc2019银川
A. Girls Band Party
大意:
给出n张牌,每张牌都有花色和名字,以及价值,只能选择不同名字的五张牌,有5种奖励名字和一种奖励花色,和奖励名字相同的名字可以提供10%的加成,相同的颜色可以提供20%的加成,这些加成可以累加到最后一起结算,问最大的价值和是多少
思路:
分组背包问题,但是需要加一个维度记录加成的等级,这样最后再计算价值和即可
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
typedef long long LL;
int t, n,level[N],dp[N][10][20];
struct node{
string name;
string color;
int val;
} a[N];
unordered_map<string, int> mp;
vector<int> g[N];
int main(){
cin>>t;
for(int j = 0;j < 6; ++j)
for(int i = 0;i < 16; ++i)
dp[0][j][i] = -0x3f3f3f3f;
while(t--){
cin>>n;
mp.clear();
int idx = 1;
for (int i = 1; i <= n;i++){
cin >> a[i].name >> a[i].color >> a[i].val;
level[i] = 0;
if(mp[a[i].name]==0){
g[idx].clear();
mp[a[i].name] = idx++;
}
g[mp[a[i].name]].push_back(i);
}
for (int i = 1; i <= 5;i++){
string name;
cin >> name;
for (int j = 1; j <= n;j++){
if(a[j].name==name){
level[j] += 1;
}
}
}
string color;
cin >> color;
for (int i = 1; i <= n;i++){
if(color==a[i].color){
level[i] += 2;
}
}
dp[0][0][0] = 0;
for (int i = 1; i < idx;i++){
for (int j = 1; j <= 5;j++){
for (int k = 0; k <= 15;k++){
dp[i][j][k] = dp[i - 1][j][k];
}
}
for (int p = 0; p < g[i].size(); p++){
for (int j = 1; j <= 5; j++){
for (int k = level[g[i][p]]; k <= 15; k++){
dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j - 1][k - level[g[i][p]]] + a[g[i][p]].val);
}
}
}
}
int res = 0;
for (int i = 0; i <= 15;i++){
res = max(res, dp[idx-1][5][i] + dp[idx-1][5][i] * i / 10);
}
cout << res << endl;
}
return 0;
}
B. So Easy
大意:
初始是一个全为0的数组,每次操作都是将一列或者一行全加1,最后选择一个数将其置为-1,现在给出最后的结果,问-1的位置在置为-1前是多少
思路:
因为数据量很小,直接暴力每一行和每一列,都减去该列(行)最小的数字,最后看-1的位置是多少
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3 + 5;
int n,mp[N][N],x,y;
int main(){
cin >> n;
for (int i = 0; i < n;i++){
for (int j = 0; j < n;j++){
cin >> mp[i][j];
if(mp[i][j]==-1){
x = i;
y = j;
}
}
}
for (int i = 0; i < n;i++){
int minn = 0x3f3f3f3f;
for (int j = 0; j < n;j++){
if(minn>mp[i][j]&&(!(i==x&&j==y))){
minn = mp[i][j];
}
}
for (int j = 0; j < n;j++){
mp[i][j] -= minn;
}
}
for (int j = 0; j < n;j++){
int minn = 0x3f3f3f3f;
for (int i = 0; i < n;i++){
if(minn>mp[i][j]&&(!(i==x&&j==y))){
minn = mp[i][j];
}
}
for (int i = 0; i < n;i++){
mp[i][j] -= minn;
}
}
cout << -(mp[x][y] + 1) << endl;
return 0;
}
F. Function!
大意:
![图片.png](https://i.loli.net/2020/11/30/fVIvtS9AjZ7lD1c.png)
(图源:https://blog.csdn.n