构造数组

构造数组

请你构造一个长度为 n 的正整数数组 a1,a2,,an

我们会给出一个长度为 n1 的由 <>= 组成的字符串 s1s2sn1 用于约束你的构造:

  • 如果 si<,则表示你构造的数组需满足 ai<ai+1
  • 如果 si>,则表示你构造的数组需满足 ai>ai+1
  • 如果 si=,则表示你构造的数组需满足 ai=ai+1

你构造的正整数数组需满足上述约束的同时,保证 a1+a2++an 的值尽可能小。

请你输出满足条件的正整数数组。数据保证一定有解

输入格式

第一行包含整数 n

第二行包含字符串 s1s2sn1

输出格式

共一行,输出 a1,a2,,an

数据范围

3 个测试点满足 2n6
所有测试点满足 2n1000

输入样例1:

5
><><

输出样例1:

2 1 2 1 2

输入样例2:

5
=<<<

输出样例2:

1 1 2 3 4

 

解题思路

  这是一道很经典的差分约束题,不过因为我不怎么熟悉所以比赛时没写出来。

  因为要求最小值,所以应该是建图跑最长路。为什么是求最长路呢,这是因为求最短路时有三角不等式,例如如果有aba是所有能直接走到b的点),那么求完最短路就会有dbda+wab。因此求最长路的话只需要把不等符号反过来,就会得到dbda+wab。因此我们只要把原问题给的约束条件都转换为ab+c这种形式,然后建图(ba连一条边,权值为c),跑最长路就可以了。

  • a=bab+0&ba+0
  • a>bab+1
  • a<bba+1

  另外,又因为每一个数都满足a>0,等价于a0+1,因此我们可以规定0号点为超级原点,d0=0。最后还需要建从0到所有点的权值为1的边。

  AC代码如下:

复制代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 1010, M = N * 3;
 5 
 6 int head[N], e[M], wts[M], ne[M], idx;
 7 int dist[N];
 8 int vis[N];
 9 
10 void add(int v, int w, int wt) {
11     e[idx] = w, wts[idx] = wt, ne[idx] = head[v], head[v] = idx++;
12 }
13 
14 void spfa() {
15     queue<int> q({0});
16     while (!q.empty()) {
17         int t = q.front();
18         q.pop();
19         vis[t] = false;
20         
21         for (int i = head[t]; i != -1; i = ne[i]) {
22             if (dist[e[i]] < dist[t] + wts[i]) {
23                 dist[e[i]] = dist[t] + wts[i];
24                 if (!vis[e[i]]) q.push(e[i]), vis[e[i]] = true;
25             }
26         }
27     }
28 }
29 
30 int main() {
31     int n;
32     cin >> n;
33     memset(head, -1, sizeof(head));
34     for (int i = 1; i < n; i++) {
35         char c;
36         cin >> c;
37         if (c == '>') add(i + 1, i, 1);         // a > b <-> a >= b + 1
38         else if (c == '<') add(i, i + 1, 1);    // a < b <-> b >= a + 1
39         else add(i, i + 1, 0), add(i + 1, i, 0);// a = b <-> a >= b + 0 and b >= a + 0
40     }
41     for (int i = 1; i <= n; i++) {  // a > 0 <-> a >= 0 + 1
42         add(0, i, 1);
43     }
44     
45     spfa();
46     
47     for (int i = 1; i <= n; i++) {
48         cout << dist[i] << ' ';
49     }
50     
51     return 0;
52 }
复制代码

 

参考资料

  AcWing 4715. 构造数组(AcWing杯 - 周赛):https://www.acwing.com/video/4525/

posted @   onlyblues  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示