@myecho
2019-03-24T13:59:38.000000Z
字数 2852
阅读 859
分治
要理解分治和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);
}
};