6.1 (2选1)
1.凸多边形三角划分的计数 (组合计数)
在一个n边形中,通过不相交于n边形内部的对角线,把n边形拆分为若干个三角形,问有多少种拆分方案?
卡特兰数通项公式:
#include"iostream"
#include"vector"
using namespace std;
vector<long long> a;
int main() {
int n;
cin >> n;
a.push_back(0);
a.push_back(1);
for (int i = 2;i <= n;i++) {
a.push_back((4 * i - 2) * 1.0 / (i + 1) * a[i - 1]);
}
cout << a[n - 2] << endl;
}
第n-2个卡特兰数即为答案
2.可重复选择的组合数问题 (组合计数)
公式:
#include"iostream"
using namespace std;
int main() {
int n, m;
cin >> n >> m;
//int a[1001];
//for (int i = 0; i <= m; i++) {
// a[i] = 1;
//}
//for (int j = 1;j <= m;j++)
// cout << a[j] << " ";
//cout << endl;
//for (int i = 2;i <= n;i++) {
// a[1] = i;
// for (int j = 2;j <= m;j++) {
// a[j] = a[j - 1] + a[j];
// }
// for (int j = 1;j <= m;j++)
// cout << a[j] << " ";
// cout << endl;
//}
//cout << a[m];
long long fz = 1, fm = 1;
for (int i = 1;i <= m;i++)fm *= i;
for (int i = n + m - 1;i >= n;i--)fz *= i;
cout << fz / fm;
}
这里只是个例子,求n个数里选m个有多少种情况
6.2 (2选1)
1.最大连续和 (动态规划)
法一:
#include"iostream"
using namespace std;
int nums[2000005];
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
int dp1, dp2;
dp1 = nums[0];
int res = dp1;
for (int i = 1;i < n;i++) {
dp2 = max(dp1 + nums[i], nums[i]);
if (dp2 > res)res = dp2;
dp1 = dp2;
}
cout << res << endl;
}
法二:
#include"iostream"
using namespace std;
int nums[2000005];
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
int res = nums[0];
int now = 0;
for (int i = 0;i < n; i++) {
now += nums[i];
if (now > res)res = now;
if (now < 0)now = 0;
}
cout << res;
}
2.最长上升子序列 (动态规划)
#include"iostream"
#include"algorithm"
#include"vector"
using namespace std;
int main() {
vector<int> nums(5005);
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
int dp[5005];
for (int i = 0;i < nums.size();i++) {
dp[i] = 1;
for (int j = 0;j <= i;j++) {
if (nums[j] < nums[i])dp[i] = max(dp[i], dp[j] + 1);
}
}
int res = 0;
for (int i = 0;i < nums.size();i++) res = max(res, dp[i]);
cout << res;
}