2020 算法上机赛 C2 - D 同步召唤
题目描述
众所周知,游戏王在5DS中出现了一种新的召唤,叫做同步召唤。
同步召唤引入了两类新的怪兽,一种被称为“协调怪兽”,另一种被称为“同步怪兽”。
每次同步召唤需要两只怪兽,一只是协调怪兽,另一只则是非协调怪兽,最终这两只怪兽会消失(也就是不能使用了),变成一只同步怪兽。请注意:同步怪兽也属于非协调怪兽。
在游戏王中,每只怪兽都有它自己的等级,而在同步召唤中,被召唤出的同步怪兽的等级等于召唤时所用的两只怪兽的等级之和。
现在你有一只等级为 1 的通常怪兽(既不属于协调怪兽,也不属于同步怪兽)和 \(n\) 只协调怪兽,你可以进行任意多次同步召唤。
请问,你可以召唤出多少种同步怪兽(如果两只同步怪兽的等级相同,则它们被视作相同)
输入
第一行包含一个正整数,为数据组数 \(T\)
接下来 \(2T\) 行,每两行对应一组输入数据
每组输入数据的第一行,包含一个正整数 \(n\) ,含义见题目描述 每组输入数据的第二行,包含 \(n\) 个正整数,表示这 \(n\) 只协调怪兽的等级
输出
对于每组数据,输出一个正整数,表示一共可以召唤出多少种不同的同步怪兽
输入样例
2
5
1 1 1 1 1
3
1 3 6
输出样例
5
7
样例解释
第一组数据可以召唤出等级为 \(2,3,4,5,6\) 的同步怪兽
第二组数据可以召唤出等级为 \(2,4,5,7,8,10,11\) 的同步怪兽
数据范围及约定
\(1\leq T\leq2000\)
\(1\leq n\leq50\)
协调怪兽的等级之和不会超过 \(1000\)
提示
所以这题是算暴力呢还是算动态规划呢
题目背景:卡牌游戏《游戏王》,动画《游戏王5DS》
老天给你用来开卡包的运气你却全用在了抽卡上(指起手五个尸块),jpg
做法
考察最基本的读题能力(x
协调怪兽的等级之和不超过 \(1000\),所以能合成出来的怪兽最大的也只有 \(1001\)
只要开一个大小为 \(1001\) 的数组,例如,用 cnt[i]
表示等级为 \(i\) 的能否被召唤
然后暴力模拟一下合并的过程就可以了
#include <bits/stdc++.h>
using namespace std;
inline int read() {
int q=0,w=1;char c=getchar();
while(!isdigit(c)){if(c=='-')w=-1;c=getchar();}
while(isdigit(c))q=q*10+c-'0',c=getchar();
return w*q;
}
const int N = 2020;
int T, n, cnt[N];
void work() {
n = read();
cnt[1] = 1;
for(int i = 1;i <= n; ++i) {
int x = read();
for(int j = 1001;j > x; --j)
cnt[j] |= cnt[j - x];
}
cnt[1] = 0;
int ans = 0;
for(int i = 1;i <= 1001; ++i) ans += cnt[i];
cout << ans << endl;
}
int main() {
T = read();
while(T--) {
memset(cnt, 0, sizeof cnt);
work();
}
return 0;
}