T1:递推134数

本题难度中等,递推计数问题,需要使用高精度

假设数码和为 i 的个数有 dp[i]

递推式:

dp[i]=dp[i1]+dp[i3]+dp[i4]

初始状态:

dp[1]=1dp[2]=1dp[3]=2dp[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 数组排序,枚举 (Li,Lj,Lk) 时,就一定有 LiLjLk

只要 Lk<Li+Lj 就能构成三角形

代码实现
#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;
}