T1:递推134数
本题难度中等,递推计数问题,需要使用高精度
假设数码和为 \(i\) 的个数有 \(dp[i]\) 个
递推式:
\[dp[i] = dp[i-1] + dp[i-3] + dp[i-4]
\]
初始状态:
\(dp[1]=1\),\(dp[2] = 1\),\(dp[3] = 2\),\(dp[4] = 4\)
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
// C = A + B
vector<int> add(vector<int> &A, vector<int> &B)
{
vector<int> C;
int t = 0;// 进位
for (int i = 0; i < A.size() || i < B.size(); i++)
{
if (i < A.size())
t += A[i];
if (i < B.size())
t += B[i];
C.push_back(t % 10);
t /= 10;
}
if (t)
C.push_back(1);
return C;
}
int main() {
int n;
cin >> n;
vector<vector<int>> dp(n+1, vector<int>(1000));
dp[1][0] = 1, dp[2][0] = 1, dp[3][0] = 2, dp[4][0] = 4;
for (int i = 5; i <= n; ++i) {
auto now = add(dp[i-1], dp[i-3]);
dp[i] = add(now, dp[i-4]);
}
int k = 999;
while (!dp[n][k]) --k;
for (int i = k; i >= 0; --i) {
cout << dp[n][i];
}
return 0;
}
T2:拼三角形
本题难度中等,直接三重枚举会超时,需要二重循环中用二分查找最后一条边。
如果知道三边大小顺序,只要判最长边是否小于另两边之和
对 \(L\) 数组排序,枚举 \((L_i, L_j, L_k)\) 时,就一定有 \(L_i \leqslant L_j \leqslant L_k\)
只要 \(L_k < L_i+L_j\) 就能构成三角形
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n;
cin >> n;
vector<int> l(n);
rep(i, n) cin >> l[i];
sort(l.begin(), l.end());
int ans = 0;
rep(i, n) {
for (int j = i+1; j < n; ++j) {
int ac = j, wa = n;
while (abs(ac-wa) > 1) {
int wj = (ac+wa)/2;
if (l[wj] < l[i]+l[j]) ac = wj;
else wa = wj;
}
ans += ac-j;
}
}
cout << ans << '\n';
return 0;
}
浙公网安备 33010602011771号