2021 ICPC 银川 B (2022 ICPC 沈阳热身赛) The Great Wall
题意:
给你一个长度为n的序列。对于每一个k,k∈[1,n].问你将其分成k个段,每个段的贡献为该段最大值-最小值。贡献总和最大值是多少.n≤1e3
分析:
很好写出一个朴素的dp
dp[i][k]=dp[j][k-1]+MAX a(j+1,i)-MIN a(j+1,i) 其中0<j<i
但是复杂度不允许 此时想如果能优化就好了 但是最大最小压根没法优化 没有传递性 所以此时再想优化一定会暴毙的
但是dp[i][k]一定是跑不掉的 这两维一定是固定的
考虑每个数是否造成贡献 一个数可能对贡献+ 对贡献— 不选他贡献0 选两次他贡献0 这四种情况
所以重新设计状态
dp[i][j][0/1/2] 表示 前i个数分成了j段 最后一段 0还没选一个数 1选了一个加数 2选了一个减数
最大化所选的数之和 最优解一定是每段的最大-最小
非常巧妙 用另一种描述的最优解 同样是题意的正解
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define vll vector<ll>
#define fi first
#define se second
const int maxn = 1e3 + 5;
const int mod = 1e9 + 7;
const int inf = 1e9;
int a[maxn] , dp[maxn][maxn][3];
int main()
{
for (int i = 0 ; i < maxn ; i++)
for (int j = 0 ; j < maxn ; j++)
for (int k = 0 ; k <= 2 ; k++)
dp[i][j][k] = -inf;
ios::sync_with_stdio(false);
int n; cin >> n;
for (int i = 1 ; i <= n ; i++) cin >> a[i];
dp[1][0][0] = 0;
for (int i = 1 ; i <= n ; i++){
for (int j = 0 ; j < i ; j++){
if (dp[i][j][0] != -inf){
// 不填
dp[i + 1][j][0] = max(dp[i + 1][j][0] , dp[i][j][0]);
// 填一个-1
dp[i + 1][j][2] = max(dp[i + 1][j][2] , dp[i][j][0] - a[i]);
// 填一个1
dp[i + 1][j][1] = max(dp[i + 1][j][1] , dp[i][j][0] + a[i]);
// 同时填 +1 -1
dp[i + 1][j + 1][0] = max(dp[i + 1][j + 1][0] , dp[i][j][0]);
}
if (dp[i][j][1] != -inf){
// 不填
dp[i + 1][j][1] = max(dp[i + 1][j][1] , dp[i][j][1]);
// 填一个-1
dp[i + 1][j + 1][0] = max(dp[i + 1][j + 1][0] , dp[i][j][1] - a[i]);
}
if (dp[i][j][2] != -inf){
// 不填
dp[i + 1][j][2] = max(dp[i + 1][j][2] , dp[i][j][2]);
// 填一个+1
dp[i + 1][j + 1][0] = max(dp[i + 1][j + 1][0] , dp[i][j][2] + a[i]);
}
}
}
for (int i = 1 ; i <= n ; i++){
cout << dp[n + 1][i][0] << endl;
}
return 0;
}
同样的一个模型
https://codeforces.com/contest/1473/problem/E
分析:
先将问题转化为 对于一条路径 我们选择一条边将其权值附为0 再选择一条边 将其权值乘2 最终要最小化答案
在最短路的时候多设置两维 dis[i][0/1][0/1] 分别是否表示选择了一条边赋值为0 是否表示选择了一条边权值乘2
因为最小化答案 最终答案一定是路径上 最大边赋值为0 最小边权值乘2
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
const int maxn = 5e5 + 5;
const int maxm = 5e5 + 5;
const int mod = 1e9 + 7;
int u[maxm] , v[maxm] , nextt[maxm] , first[maxn] , sign;
ll w[maxm];
void addedge(int x , int y , int z){
u[++sign]=x;
v[sign]=y;
w[sign] = z;
nextt[sign]=first[x];
first[x]=sign;
}
struct Node{
ll id , dis;
int s0 , s1;
Node (int n = 0, ll d = 1e17 , int s0 = 0 , int s1 = 0)
{
id = n;dis = d;
this->s0 = s0;
this->s1 = s1;
}
bool operator < (const Node & a)const
{
return dis > a.dis;
}
};
int book[maxn][2][2] , n , m;
ll dis[maxn][2][2];
void Dijstra(ll s){
priority_queue<Node>q;
while(q.size()) q.pop();
for (int i = 1 ; i <= n ; i++){
for (int j = 0 ; j <= 1 ; j++){
for (int k = 0 ; k <= 1 ; k++){
book[i][j][k] = 0;
dis[i][j][k] = 1e16;
}
}
}
dis[s][0][0] = 0;
q.push(Node(s , 0 , 0 , 0));
while(q.size())
{
Node g = q.top() ; q.pop();
int id = g.id;
ll dist = g.dis;
int s0 = g.s0 , s1 = g.s1;
if (book[id][s0][s1]) continue;
book[id][s0][s1] = 1;
for (int i = first[id] ; i ; i = nextt[i]){
if (dis[v[i]][s0][s1] > dist + w[i]){
dis[v[i]][s0][s1] = dist + w[i];
q.push(Node(v[i] , dis[v[i]][s0][s1] , s0 , s1));
}
if (!s0 && dis[v[i]][1][s1] > dist){
dis[v[i]][1][s1] = dist;
q.push(Node(v[i] , dis[v[i]][1][s1] , 1 , s1));
}
if (!s1 && dis[v[i]][s0][1] > dist + 2 * w[i]){
dis[v[i]][s0][1] = dist + 2 * w[i];
q.push(Node(v[i] , dis[v[i]][s0][1] , s0 , 1));
}
if (!s0 && !s1 && dis[v[i]][1][1] > dist + w[i]){
dis[v[i]][1][1] = dist + w[i];
q.push(Node(v[i] , dis[v[i]][1][1] , 1 , 1));
}
}
}
return ;
}
int main()
{
ios::sync_with_stdio(false);
cin >> n >> m;
for (int i = 1 ; i <= m ; i++){
int x , y , z; cin >> x >> y >> z;
addedge(x , y , z);
addedge(y , x , z);
}
Dijstra(1);
for (int i = 2 ; i <= n ; i++){
cout << dis[i][1][1] << " ";
}
cout << endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
2021-11-17 回归第一题