不知道这个算不算剪枝,小白一个......
题目描述:
给出一个长度为n的数列A𝑖,问是否能将这个数列分解为两个长度
为n/2的子序列,满足
∙ 两个子序列不互相重叠。
∙ 两个子序列中的数要完全一样,{1, 2} = {1, 2},{1, 2} ≠ {2, 1}。
输入描述:
第一行,一个正整数T,表示数据组数。
接下来T组数据,每组数据的第一行,一个正整数n,第二行𝑛个正整数A𝑖。
输出描述:
每组数据输出一行,如果可以完成,输出Frederica Bernkastel,否则输出Furude Rika。
示例1
输入
复制
3
4
1 1 2 2
6
1 2 3 4 5 6
4
1 2 2 1
输出
复制
Frederica Bernkastel
Furude Rika
Furude Rika
解题思路:
1.考虑数据的大小,直接搜索必然超时,所以考虑用空间节约时间的方法。创建2个数组用来保存数字,进行匹配。
2.考虑用三指针的思想来处理数据,aIndex,bIndex,arrIndex,分别对应三个数组的索引(三个指针).
3.搜索方法是首先将arr第一个数字默认放进a数组里,遍历原数组arr,同时进行判定,是否是b数组索引对应的a数组的数字(这里可能有点绕,其实就是相匹配的数字)。
4.搜索面对的是两种情况:
相匹配的情况下,就可以尝试(用if去尝试 )去放进b数组之中,如果不行,就放进a数组之中;
不匹配的话直接放进a数组之中。
5.终止条件首先判断是否超出一半,其次是未超出一半的同时,arr数组遍历完毕(代表互相匹配成功)
int arr[50],a[50],b[50]; int aIndex, bIndex, arrIndex;//三个数组索引 a 和 b 的索引也代表他们的数字个数 #include<iostream> int n; using namespace std; // 其实就两种情况 判断arr里面的这个数字 是否对应 不对应 直接丢a里 对应就去尝试丢b里面的情况 直到最后 来判断结果 int dfs(int aIndex, int bIndex, int arrIndex) { if (aIndex > n / 2 || bIndex > n / 2) { return 0; } //数组都没用掉一半 if (arrIndex > n) { return 1; } if (arr[arrIndex] == a[bIndex+1]) { b[bIndex + 1] = arr[arrIndex]; if (dfs(aIndex, bIndex + 1, arrIndex+1)) { return 1; } //回溯消除选择选择状态 b[bIndex + 1] = 0;//清除掉 可以省略 主要是思想的体现 } a[aIndex + 1] = arr[arrIndex]; return dfs(aIndex + 1, bIndex, arrIndex + 1); } int main() { ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); int t; cin >> t; while (t--) { cin >> n; for (int i = 1; i <= n; i++) { cin >> arr[i]; } a[1] = arr[1];//先把一个丢进去 if (dfs(1, 0, 2)) { cout << "Frederica Bernkastel\n"; } else { cout << "Furude Rika\n"; } } }