@myecho
2019-03-24T21:59:38.000000Z
字数 2852
阅读 734
分治
要理解分治和backtracking的区别:
Backtracking is a general algorithm for finding all (or some)
solutions to some computational problems, notably constraint
satisfaction problems, that incrementally builds candidates to the
solutions, and abandons a candidate ("backtracks") as soon as it
determines that the candidate cannot possibly be completed to a valid
solution.
分治是一定有处理子问题的调用,将大的问题分而治之。
1 URAL 11129
题目大意:给定0~n-1的自然数,给出其子序列不可能出现等差序列的一种排列,1243是不符合条件的,因为其子序列123为子序列。
思路:通过递归,首先将序列分开奇偶序列,这样奇数序列和偶数序列之间是不会产生等差序列的了,从而将大的问题转化为较小的问题,然后递归下去,注意下边界条件即可。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int array[10010], tmp[10010];
void Dvide(int l, int r)
{
if(r - l <= 1) return;
for(int i = l; i <= r; i++)
tmp[i] = array[i];
int i, j;
for(i = l, j = l; j <= r; j += 2, i++){
array[i] = tmp[j];
}
for(j = l + 1; j <= r; j += 2, i++){
array[i] = tmp[j];
}
Dvide(l, (l + r) / 2);
Dvide((l + r) / 2 + 1, r);
}
int main()
{
int n;
while(scanf("%d", &n) && n){
for(int i = 0; i < n; i++)
array[i] = i;
Dvide(0, n - 1);
printf("%d:", n);
for(int i = 0; i < n; i++)
printf(" %d", array[i]);
printf("\n");
}
return 0;
}
关于子序列的问题还有很多,如最大子序列、最长公共子串、最长公共子序列、最长递增子序列等。这些问题都放到dp专题里边了。
int count(int m,int n)//m apples
{
if(m==0||n==1) return 1;
if(n>m) return count(m,m);
return count(m-n,n)+count(m,n-1);
}
leetcode Different Ways to Add Parentheses
class Solution {
public:
vector divide(string input) {
vector<int> ans;
//用来标记是否是一个表达式
bool isAlgo = false;
for(int i = 0; i < input.size(); ++i) {
if (input[i] == '*') {
vector<int> ans1 = divide(input.substr(0, i));
vector<int> ans2 = divide(input.substr(i+1, input.size() - i - 1));
for(int i = 0; i < ans1.size(); ++i) {
for(int j = 0; j < ans2.size(); ++j) {
ans.push_back(ans1[i]*ans2[j]);
}
}
isAlgo = true;
} else if (input[i] == '-') {
vector<int> ans1 = divide(input.substr(0, i));
vector<int> ans2 = divide(input.substr(i+1, input.size() - i - 1));
for(int i = 0; i < ans1.size(); ++i) {
for(int j = 0; j < ans2.size(); ++j) {
ans.push_back(ans1[i]-ans2[j]);
}
}
isAlgo = true;
} else if (input[i] == '+') {
vector<int> ans1 = divide(input.substr(0, i));
vector<int> ans2 = divide(input.substr(i+1, input.size() - i - 1));
for(int i = 0; i < ans1.size(); ++i) {
for(int j = 0; j < ans2.size(); ++j) {
ans.push_back(ans1[i]+ans2[j]);
}
}
isAlgo = true;
}
}
if (isAlgo)
return ans;
else
return vector<int>{stoi(input)};
}
vector<int> diffWaysToCompute(string input) {
if (input.size() == 0)
return vector<int>{};
return divide(input);
}
};