2026-01-20
CF
Problem - 1829G - Codeforces(dp好题)
状态转移方程:
\[f_{i,j}= \begin{cases} 1 & i=1 \\ f_{i-1,j-1} + f_{i-1,j} - f_{i-2,j-1} & i>1 \end{cases}
\]
要注意这里需要减去\(f_{i-2,j-1}\)(两者重叠部分)
这里要求2023行,要估算数组多大
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const LL mod = 998244353;
const int N=3e6+10;
LL ans[N],a[2030][2030];
void solve()
{
int n;
cin >> n;
cout << ans[n] << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T;
cin >> T;
LL cnt = 0;
for (int i = 1; i <= 2023;i++){
for (int j = 1; j <= i;j++){
cnt++;
a[i][j] = cnt * cnt;
}
}
cnt = 0;
for (int i = 2; i <= 2023; i++){
for (int j = 1; j <= i;j++){
a[i][j] += a[i-1][j - 1] + a[i-1][j] - a[i - 2][j - 1];
}
}
for (int i = 1; i <= 2023;i++){
for (int j = 1; j <= i;j++){
ans[++cnt] = a[i][j];
}
}
while (T--)
{
solve();
}
}
Problem - 888D - Codeforces
数学题
\(C(n,i+1)=C(n,i)×\frac{n-i}{i+1}\)
要先推出来对于1,2,3,4个数字不同时,可能的排列,注意时完全不同
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const LL mod = 998244353;
const int N=2e5+10;
LL n, k, C, res;
LL d[] = {1, 0, 1, 2, 9};
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> k;
C = 1;
for (int i = 0; i <= k; i++){
res += d[i] * C;
C = C * (n - i) / (i + 1);
}
cout << res << endl;
}
Problem - 38E - Codeforces(dp)
题意:先搞清楚总花费
- 卡针的费用总和;
- 每个弹珠的路径长度总和,即弹珠初始位置和最终位置之间差值的绝对值总和。
有 n 个弹珠,对于第 i 个弹珠,有两种选择:
- 定住,花费 \(c_i\)
- 不定,花费为这个弹珠到左侧第一个定住弹珠的距离,设这个左侧第一个定住弹珠为 j,即花费为 \(x_i−x_j\)
时间复杂度为:\(O(n^2)\)
f[i] = min(f[i], f[j] + (s[i - 1] - s[j]) - a[j].x * (i - j - 1) + a[i].c);
f[i]即为定住第 \(i\) 个弹珠的最小花费,因为已经按距离从小到大排序了,因此找到左边定住的弹珠 \(j\),在 \(j\) 之前花费为 \(f_j\),再加上 \(i\) 到 \(j\) 之间 \(i-1-j\) 颗弹珠从初始到 \(j\) 的距离的花费(注意,向左滚,数值越滚越小),再加上钉上 \(i\) 第 \(i\) 颗弹珠的花费
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const LL mod = 998244353;
const int N=2e5+10;
struct node{
LL x, c;
bool operator<(const node &a)const{
return x < a.x;
}
} a[N];
LL n, s[N], f[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n;
for (int i = 1; i <= n;i++){
cin >> a[i].x >> a[i].c;
}
sort(a + 1, a + 1 + n);
n++;
a[n].x = a[n - 1].x + 1;//加上一个,因为要考虑最后一个也有定不定住的情况
a[n].c = 0;
for (int i = 1; i <= n;i++){
s[i] = s[i - 1] + a[i].x;
f[i] = f[i - 1] + a[i].c;
for (int j = 1; j < i;j++){
f[i] = min(f[i], f[j] + (s[i - 1] - s[j]) - a[j].x * (i - j - 1) + a[i].c);
}
}
cout << f[n] << endl;
}
天梯赛刷题记录
L1-002 打印沙漏 - 团体程序设计天梯赛-练习集(模拟)
#include <iostream>
using namespace std;
int main()
{
int n;
char c;
cin >> n;
cin >> c;
int l = 0;
int sum = 0;
while (sum <= (n + 1) / 2)//找一半需要多少行
{
l++;
sum += (l * 2 - 1);
}
sum -= (l * 2 - 1);
l--;
for (int i = l; i > 0; i--)//倒三角
{
for (int k = 0; k < l - i; k++)
cout << " ";
for (int j = 0; j < i * 2 - 1; j++)
cout << c;
cout << endl;
}
for (int i = 2; i <= l; i++)//正三角,不包含 1的
{
for (int k = 0; k < l - i; k++)
cout << " ";
for (int j = 0; j < i * 2 - 1; j++)
cout << c;
cout << endl;
}
cout << n - sum * 2 + 1 << endl;//输出剩余部分
return 0;
}
L1-003 个位数统计 - 团体程序设计天梯赛-练习集(map使用)
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const LL mod = 998244353;
const int N=2e5+10;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
string s;
cin >> s;
map<int, int> a;
for (int i = 0; i < s.size();i++){
a[s[i] - '0']++;
}
for(auto i:a){
cout << i.first<<":"<<i.second << endl;
}
}
L1-004 计算摄氏温度 - 团体程序设计天梯赛-练习集
#include<iostream>
using namespace std;
int f;
int main() {
cin >> f;
int c = 5*(f - 32) / 9;
cout << "Celsius = " << c << endl;
return 0;
}
L1-005 考试座位号 - 团体程序设计天梯赛-练习集(结构体)
通过试机座位号推准考证号和考试座位号
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const LL mod = 998244353;
const int N=2e5+10;
struct student{
string st;
int num;
} a[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n,idx,number;
string s;
cin >> n;
for (int i = 0; i < n;i++){
cin >> s;
cin >> idx >> number;
a[idx].st = s;
a[idx].num = number;
}
int m;
cin >> m;
int x;
while(m--){
cin >> x;
cout << a[x].st << " " << a[x].num << endl;
}
}
L2-001 紧急救援 - 团体程序设计天梯赛-练习集(dijkstra)
最短路问题,同时还要计算最短路径的条数和路上救援队的数量的最大值
注意:这里是从0开始记录城市
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const LL mod = 998244353;
const int N=510;
int c[N],mx[N],num[N],pre[N];
int dist[N],vis[N];
struct node{
int v, w;
};
vector<node> e[N];
int n, m, s, d;
void Path(int v){//输出
if(v==s){
cout << v;
return;
}
Path(pre[v]);
cout <<" "<< v;
}
void dijkstra(){
memset(dist, 0x3f, sizeof dist);
dist[s] = 0;
mx[s] = c[s];//救援队最大数量
for (int i = 0; i < n;i++){
int u = -1;//注意
// 找到未访问的最近节点
for (int j = 0; j < n; j++){//这样找点
if (!vis[j] && (u == -1 || dist[j] < dist[u]))
u = j;
}
vis[u] = true;
for(auto ed:e[u]){
int v = ed.v, w = ed.w;
if(dist[v]>=dist[u]+w){
if(dist[v]==dist[u]+w){
num[v] += num[u];
if(mx[v]<mx[u]+c[v]){
mx[v] = mx[u]+c[v];//直接更新这条路的救援队数量,而不是累加
pre[v] = u;//只有需要更新才记录前驱
}
}
else{
num[v] = num[u];
mx[v] = mx[u]+c[v];
dist[v] = dist[u] + w;
pre[v] = u;
}
}
}
}
cout << num[d] << " " << mx[d] << endl;
Path(d);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m >> s >> d;
for (int i = 0; i < n;i++){
cin >> c[i];
}
for (int i = 0; i < m;i++){
int a, b, w;
cin >> a >> b >> w;
e[a].push_back({b, w});
e[b].push_back({a, w});
}
num[s] = 1;
dijkstra();
}

浙公网安备 33010602011771号