A Girls Band Party
分组背包
#include<bits/stdc++.h>
#define ll long long
using namespace std;
map<string, int> mp1, mp2;
int dp[100010][6][16];
struct node
{
string name, color;
int val, num;
} card[100010];
vector<node> v[100010];
int cmp(node x, node y)
{
return x.name < y.name;
}
int main()
{
int t, n;
cin >> t;
while (t--)
{
cin >> n;
memset(dp, -1, sizeof(dp));
mp1.clear();
mp2.clear();
for (int i = 1; i <= n; i++)
{
v[i].clear();
}
for (int i = 1; i <= n; i++)
{
cin >> card[i].name >> card[i].color >> card[i].val;
}
string use;
for (int i = 1; i <= 5; i++)
{
cin >> use;
mp1[use] = 1;
}
cin >> use;
mp2[use] = 2;
sort(card + 1, card + 1 + n, cmp);
int cnt = 0;
// 每种名字一个vector
for (int i = 1; i <= n; i++)
{
if (card[i].name != card[i - 1].name)
{
cnt++;
}
card[i].num = mp1[card[i].name] + mp2[card[i].color];
v[cnt].push_back(card[i]);
}
dp[0][0][0] = 0;//物品,选几个,恰好多少buff
for (int i = 1; i <= cnt; i++)
{
for (int k = 0; k <= 5; k++)//不选
{
for (int q = 0; q <= 15; q++)
{
dp[i][k][q] = dp[i - 1][k][q];
}
}
for (int j = 0; j < v[i].size(); j++)//选择
{
int val = v[i][j].val, num = v[i][j].num;
for (int k = 1; k <= 5; k++)
{
for (int q = num; q <= 15; q++)
{
if (dp[i - 1][k - 1][q - num] != -1)
{
dp[i][k][q] = max(dp[i][k][q], dp[i - 1][k - 1][q - num] + val);
}
}
}
}
}
int ans = 0;
for (int j = 0; j <= 15; j++)
{
ans = max(ans, dp[cnt][5][j] * (10 + j) / 10);
}
printf("%d\n", ans);
}
return 0;
}
B
ai,j - ai,j+1 = ai+1,j - ai+1,j+1
因为:
变行:差值不变(只改变了一边的被减数和减数)
变列:同时增加了减数或者被减数
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define db double
#define pii pair<int, int>
#define psi pair<string, int>
#define ull unsigned ll
#define pb push_back
#define mp make_pair
#define X first
#define Y second
#define ld long double
const int N = 1E3 + 7;
#define INF ~0ULL
int arr[N][N];
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
cin >> arr[i][j];
int x, y;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
if (arr[i][j] == -1)
x = i, y = j;
int ans = 0;
if (x + 1 <= n)
{ //可以向下拓展
if (y + 1 <= n) //可以向右拓展
ans = arr[x][y + 1] + arr[x + 1][y] - arr[x + 1][y + 1];
else
ans = arr[x][y - 1] + arr[x + 1][y] - arr[x + 1][y - 1];
}
else
{
if (y + 1 <= n)
ans = arr[x - 1][y] + arr[x][y + 1] - arr[x - 1][y + 1];
else
ans = arr[x - 1][y] + arr[x][y - 1] - arr[x - 1][y - 1];
}
cout<<ans<<endl;
}
C
D
E
F
G
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 7;
int n, m;
struct node
{
int l, r, mx;
int mx2, la2;
int mx3, la3;
int mx5, la5;
int mx7, la7;
} t[N << 2];
void update(int k)
{ //更新单个节点
t[k].mx2 = max(t[k << 1].mx2, t[k << 1 | 1].mx2);
t[k].mx3 = max(t[k << 1].mx3, t[k << 1 | 1].mx3);
t[k].mx5 = max(t[k << 1].mx5, t[k << 1 | 1].mx5);
t[k].mx7 = max(t[k << 1].mx7, t[k << 1 | 1].mx7);
t[k].mx = max(t[k << 1].mx, t[k << 1 | 1].mx);
}
void pushdown(int k)
{ //lazytagdown
if (t[k].la2)
{
t[k << 1].la2 += t[k].la2;
t[k << 1 | 1].la2 += t[k].la2;
t[k << 1].mx2 += t[k].la2;
t[k << 1 | 1].mx2 += t[k].la2;
t[k].la2 = 0;
}
if (t[k].la3)
{
t[k << 1].la3 += t[k].la3;
t[k << 1 | 1].la3 += t[k].la3;
t[k << 1].mx3 += t[k].la3;
t[k << 1 | 1].mx3 += t[k].la3;
t[k].la3 = 0;
}
if (t[k].la5)
{
t[k << 1].la5 += t[k].la5;
t[k << 1 | 1].la5 += t[k].la5;
t[k << 1].mx5 += t[k].la5;
t[k << 1 | 1].mx5 += t[k].la5;
t[k].la5 = 0;
}
if (t[k].la7)
{
t[k << 1].la7 += t[k].la7;
t[k << 1 | 1].la7 += t[k].la7;
t[k << 1].mx7 += t[k].la7;
t[k << 1 | 1].mx7 += t[k].la7;
t[k].la7 = 0;
}
t[k << 1].mx = max({t[k << 1].mx2, t[k << 1].mx3, t[k << 1].mx5, t[k << 1].mx7});
t[k << 1 | 1].mx = max({t[k << 1 | 1].mx2, t[k << 1 | 1].mx3, t[k << 1 | 1].mx5, t[k << 1 | 1].mx7});
}
void build(int k, int l, int r)
{
//jianshu
t[k].l = l;
t[k].r = r;
t[k].mx2 = t[k].mx3 = t[k].mx5 = t[k].mx7 = 0;
t[k].la2 = t[k].la3 = t[k].la5 = t[k].la7 = 0;
if (l == r)
return;
int mid = (l + r) >> 1;
build(k << 1, l, mid);
build(k << 1 | 1, mid + 1, r);
update(k);
}
void addsegement(int k, int l, int r, int x2, int x3, int x5, int x7)
{ //updatesegement
if (t[k].l >= l && t[k].r <= r)
{
t[k].la2 += x2, t[k].la3 += x3, t[k].la5 += x5, t[k].la7 += x7;
t[k].mx2 += x2, t[k].mx3 += x3, t[k].mx5 += x5, t[k].mx7 += x7;
t[k].mx = max({t[k].mx2, t[k].mx3, t[k].mx5, t[k].mx7});
return;
}
pushdown(k);
int mid = (t[k].l + t[k].r) >> 1;
if (r > mid)
addsegement(k << 1 | 1, l, r, x2, x3, x5, x7);
if (l <= mid)
addsegement(k << 1, l, r, x2, x3, x5, x7);
update(k);
}
int query(int k, int l, int r)
{
if (t[k].l >= l && t[k].r <= r)
return t[k].mx;
pushdown(k);
int x = 0;
int mid = (t[k].l + t[k].r) >> 1;
if (mid < r)
x = max(x, query(k << 1 | 1, l, r));
if (mid >= l)
x = max(x, query(k << 1, l, r));
return x;
}
int main()
{
cin >> n >> m;
string s;
int x, y, z;
build(1, 1, n); //k
for (int i = 1; i <= m; i++)
{
cin >> s;
if (s[1] == 'U')
{
scanf("%d%d%d", &x, &y, &z);
int x2, x3, x5, x7;
x2 = x3 = x5 = x7 = 0;
if (z == 2)
x2++;
else if (z == 3)
x3++;
else if (z == 4)
x2 += 2;
else if (z == 5)
x5++;
else if (z == 6)
x2++, x3++;
else if (z == 7)
x7++;
else if (z == 8)
x2 += 3;
else if (z == 9)
x3 += 2;
else if (z == 10)
x2++, x5++;
addsegement(1, x, y, x2, x3, x5, x7);
}
else
{
scanf("%d%d", &x, &y);
printf("ANSWER %d\n", query(1, x, y));
}
}
return 0;
}
H
I
模拟
#include <bits/stdc++.h>
using namespace std;
const int N = 1000;
char s1[N], s2[N];
int a[N], t[N], n, m; //n进制转m
void solve()
{
int len = strlen(s1), i, k;
for (i = 0; i < len; ++i)
t[len - i - 1] = s1[i] - (s1[i] < 65 ? 48 : s1[i] < 97 ? 55
: 61); //字符串s1转整型数组t 逆序:低位在前高位在后
for (k = 0; len;)
{
for (i = len; i > 0; --i)
{ //对n进制的t短除 从最高位t[len-1]开始 在最后一位t[0]前停下
t[i - 1] += t[i] % m * n; //高位除不尽的(t[i]%m) 乘上n(n进制数) 再加到低位t[i-1]上
t[i] /= m; //该高位 上 t[i]/m 转成m进制
}
a[k++] = t[0] % m;
t[0] /= m; //单独处理最后一位
while (len && !t[len - 1])
--len; //第len位一定是处理完的了(第一次白做),找第len位后不为0的位
}
s2[k] = 0;
for (i = 0; i < k; ++i)
s2[k - i - 1] = a[i] + (a[i] < 10 ? 48 : a[i] < 36 ? 55
: 61);
}
int main()
{
scanf("%d%d%s", &n, &m, &s1);
solve();
printf("%s\n", s2);
return 0;
}