A. Find The Array
题意
要你构造一个长度为$n$的数组,每个元素$a_i$满足:
- $a_i=1$
- $a_i-1$或者$a_i-2$存在于数组中
现在要你构造一个元素和为$s$的数组,问最短长度为多少
分析
贪心,让数组元素尽量大,但是因为$a_i-2$必须在数组中,所以构造的是$1,3,5,7,…$. 最后一个数如果溢出可以将其减小至和恰好为$s$,不影响性质。
代码
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 
 | #include <bits/stdc++.h>#define fors(i, a, b) for(int i = (a); i <= (b); ++i)
 #define lson k<<1
 #define rson k<<1|1
 #define pb push_back
 #define lowbit(x) ((x)&(-(x)))
 #define mem(a) memset(a, 0, sizeof(a))
 #define DDLC_ESCAPE_PLAN_FAILED ios::sync_with_stdio(false), cin.tie(0)
 #define int long long
 const int inf = 0x3f3f3f3f;
 const double dinf = 1e100;
 typedef long long ll;
 
 
 using namespace std;
 
 signed main()
 {
 DDLC_ESCAPE_PLAN_FAILED;
 int t;
 cin >> t;
 while(t--)
 {
 int sum = 0;
 int n;
 cin >> n;
 for(int i = 1; ; i += 2){
 sum += i;
 if(sum >= n){
 cout << (i + 1) / 2 << endl;
 break;
 }
 }
 }
 return 0;
 }
 
 | 
B. Maximum Cost Deletion
题意
给一个01串。每次操作可以选其中连续一段由相同字符构成的子串并将其删除。删除后剩下的部分保留顺序,拼接起来。每次删可以得到$a·l+b$分($l$为删的长度)。问删完后最大得分是多少
分析
考虑串中每个元素的平均贡献,即$\frac{a·l+b}{l}=a+\frac{b}{l}$. 由此可知不管怎么删,每个元素都一定会贡献$a$分。有变数的只有$b$. 当$b\geq 0$,应让$l$尽量小来最大化分数,所以$l=1$,答案是$总长度·(a+b)$;而若$b<0$,尽量让$l$变大。所以尽可能地扩展长度,每次都把整个连续的串删掉。
这个时候,把字符串分成$x$块,每块都是最长的连续的0或者1,这些块的邻居肯定是不同字符。每次删除之后,相邻字符会拼接起来。每次一个块一个块地删,最后总共删$x/2+1$次. 则答案为$a·l+(x/2+1)·b$
代码
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 
 | #include <bits/stdc++.h>#define fors(i, a, b) for(int i = (a); i <= (b); ++i)
 #define lson k<<1
 #define rson k<<1|1
 #define pb push_back
 #define lowbit(x) ((x)&(-(x)))
 #define mem(a) memset(a, 0, sizeof(a))
 #define DDLC_ESCAPE_PLAN_FAILED ios::sync_with_stdio(false), cin.tie(0)
 #define int long long
 const int inf = 0x3f3f3f3f;
 const double dinf = 1e100;
 typedef long long ll;
 
 
 using namespace std;
 
 signed main()
 {
 DDLC_ESCAPE_PLAN_FAILED;
 int t;
 cin >> t;
 while(t--)
 {
 int n, a, b;
 string s;
 cin >> n >> a >> b >> s;
 if(b > 0){
 cout << (int)s.size() * (a + b) << endl;
 }
 else{
 char now = '.';
 int cnt = 0;
 for(int i = 0; i < s.size(); ++i){
 if(s[i] != now){
 now = s[i];
 cnt++;
 }
 }
 cout << (cnt / 2LL + 1LL) * b + a * (int)s.size() << endl;
 }
 }
 return 0;
 }
 
 | 
C. Manhattan Subarrays
题意
给数组$a$,则规定其对应了平面上$n$个点$(a_1,1),(a2,2),…(a_i,i)…$ 现在要求选出一个连续子数组,保证其长度小于3,或者从其中任选3个点$x,y,z$,不可能有$d(x,y)+d(y,z)=d(x,z)$。其中$d(x,y)$为$(a_x,x)$和$(a_y,y)$的曼哈顿距离](https://baike.baidu.com/item/曼哈顿距离/743092)),问可选出多少这样的子数组。
分析
由于各个点的$y$坐标都不一样,可以画图。随意在坐标图上画3个$y$坐标两两不同的点,改变它们$x$坐标之间的关系。可以发现,当按$y$坐标顺序看这三个点时,当且仅当它们的$x$坐标单调不下降或者单调不上升时,有$d(x,y)+d(y,z)=d(x,z)$。
那么对于长度为4的子数组,我们需要判断4次,每次从其中任选3个判断一下。
但对于长度5的数组,我们发现,不管怎么画,都必定会出现$d(x,y)+d(y,z)=d(x,z)$。
因此,满足条件的数组最长长度为4。而长度为2,1的必定符合条件,故我们只需判断长度为3,4的即可。
代码
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 
 | #include <bits/stdc++.h>#define fors(i, a, b) for(int i = (a); i <= (b); ++i)
 #define lson k<<1
 #define rson k<<1|1
 #define pb push_back
 #define lowbit(x) ((x)&(-(x)))
 #define mem(a) memset(a, 0, sizeof(a))
 #define DDLC_ESCAPE_PLAN_FAILED ios::sync_with_stdio(false), cin.tie(0)
 #define int long long
 const int inf = 0x3f3f3f3f;
 const double dinf = 1e100;
 typedef long long ll;
 
 
 using namespace std;
 const int maxn = 2e5 + 10;
 int a[maxn];
 bool check(int x, int y, int z)
 {
 if(a[x] <= a[y] && a[y] <= a[z]) return 0;
 if(a[x] >= a[y] && a[y] >= a[z]) return 0;
 return 1;
 }
 signed main()
 {
 DDLC_ESCAPE_PLAN_FAILED;
 int t;
 cin >> t;
 while(t--)
 {
 int n;
 cin >> n;
 fors(i, 1, n) cin >> a[i];
 int ans = 2 * n - 1;
 for(int len = 3; len <= 4; ++len){
 for(int l = 1; l + len - 1 <= n; ++l){
 if(len == 3 && check(l, l + 1, l + 2)) ans++;
 else if(len == 4 && (check(l, l + 1, l + 2) && check(l, l + 2, l + 3) && check(l + 1, l + 2, l + 3) && check(l, l + 1, l + 3))) ans++;
 }
 }
 cout << ans << endl;
 }
 return 0;
 }
 
 |