0%

小明的新游戏(京东笔试题C++开发2020.08.27场)

好久没有写博客了,回学校了也没啥时间可以摸鱼了(主要还是懒🤣)

晚上参加了东哥家的笔试,30道选择+两道编程。整体难度还好,(Ball Ball 东哥给孩子一个机会吧!看在老PLUS会员的份上)

但是第二道编程题想要记录一下,最后一分钟才调出来,刺激!🤪

题目

从CSDN上扒了张题图。

alt

思路:

第一眼看过去,这就是一道典型的完全背包求方案数的问题呀!刷刷把完全背包写了一遍。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;

typedef long long LL;
const int N = 110, M = 1010, mod = 1e9 + 7;
int vals[N];
LL f[N][M];//f[i][j]表示只从前i张卡片中选,恰好可以打掉BOSS的血量为j的方案数

int main()
{
int n, m;
cin >> n >> m;
for(int i = 1; i <= n; ++i)
cin >> vals[i];
for(int i = 0; i <= n; ++i)
f[i][0] = 1;//魔王0滴血,不用出牌也算一种方案
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
for(int k = 0; k <= j / vals[i]; ++k)
f[i][j] = (f[i][j] + f[i - 1][j - k * vals[i]]) % mod;
cout << f[n][m] << endl;
return 0;
}

信心满满自测样例……(淦,咋对不上?尴尬)没事,可能是我完全背包太久没写哪里出了点差错,调就完事儿了。

30 Minutes Later~~

淦,这完全背包没毛病呀?到底啥情况?样例倒是为什么会是5,我手工模拟也是3(黑人问号???)

终于想起来再读一遍题目。

“使用的牌的种类或数量不同代表不同的方案,改变牌的顺序同样代表不同的方案

真想扇死自己,题都没读完直接开敲,hh。

AC代码及思路:

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
30
31
32
33
#include <iostream>
#include <algorithm>
using namespace std;

typedef long long LL;
const int N = 110, M = 1010, mod = 1e9 + 7;
int vals[N];
//LL f[N][M];//f[j][i],注意是f[j][i],表示只从前j张卡片中选,恰好可以打掉BOSS的血量为i的方案数
LL f[M];

int main()
{
int n, m;
cin >> n >> m;
for(int i = 1; i <= n; ++i)
cin >> vals[i];
sort(vals + 1, vals + n + 1);//后来想想没有必要
//f[j][i]此时可以理解为当BOSS的血量为i时,小明的最后一次攻击使用的是第j张牌的总方案数
/*for(int i = 0; i <= n; ++i)
f[i][0] = 1;//魔王0滴血,不用出牌也算一种方案
for(int i = 1; i <= m; ++i)
for(int j = 1; j <= n; ++j)
if(i >= vals[j])
f[j][i] = (f[j][i] + f[j - 1][i - vals[j]]) % mod;*/
//优化成一维的,同层转移
f[0] = 1;
for(int i = 1; i <= m; ++i)
for(int j = 1; j <= n; ++j)
if(i >= vals[j])
f[i] = (f[i] + f[i - vals[j]]) % mod;
cout << f[m] << endl;
return 0;
}

稍微解释一下为什么要把背包体积放第一维,物品编号放第二维就可以算出考虑顺序的方案数。

原始状态表示为f[j][i],即当BOSS的血量为 i 时,小明的最后一次攻击能恰好击杀时使用的是第 j 张牌的总方案数。此时在BOSS血量为某一确定值的前提下,需要循环遍历所有牌并判断其是否能作为此时的最后一击,这里其实就暗含了一个出牌的顺序。

优化成一维也很显然,即满足公式f[i] += f[i - vals[j]],含义为血量为 i 时考虑顺序差异的方案总数。