AtCoder Beginner Contest 099

C

由于可以装的是有限个,因此可以全部都装进去,紧接着用一个完全背包进行枚举即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// LUOGU_RID: 174639729
#include <bits/stdc++.h>
using namespace std;
int n, cnt, a[233], f[1000010], p;
int main()
{
cin >> n;
a[++cnt] = 1;
p = 1;
for (int i = 1; i <= 8; i++)
{
p *= 6;
a[++cnt] = p;
}
p = 1;
for (int i = 1; i <= 6; i++)
{
p *= 9;
a[++cnt] = p;
}
sort(a + 1, a + cnt + 1);
memset(f, 0x3f, sizeof(f));
f[0] = 0;
for (int i = 1; i <= cnt; i++)
for (int j = a[i]; j <= n; j++)
f[j] = min(f[j], f[j - a[i]] + 1);
cout << f[n];
return 0;
}

D

分成3组,统一计算,最后暴力枚举即可,颜色数量是满足题意的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// LUOGU_RID: 174644485
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 50, M = 3, inf = 2e18;
long long n, m, s, x, i, j, k, ans = inf, c[N][N], f[M][N];
int main()
{
cin >> n >> m;
for (i = 1; i <= m; i++)
for (j = 1; j <= m; j++)
cin >> c[i][j];
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
{
s = (i + j) % 3;
cin >> x;
for (k = 1; k <= m; k++)
f[s][k] += c[x][k];
}
for (i = 1; i <= m; i++)
for (j = 1; j <= m; j++)
for (k = 1; k <= m; k++)
if (i != j && i != k && j != k)
ans = min(ans, f[0][i] + f[1][j] + f[2][k]);
cout << ans << '\n';
}