Ribbon on the Christmas Present(色带染色)
You are preparing a ribbon to decorate the Christmas present box. You plan to dye the ribbon, initially white, to make a stripe pattern of different shades of red. The ribbon consists of a number of sections, each of which should be dyed as planned.
You want to prepare the ribbon with the least number of dyeing steps. Contiguous sections of the ribbon can be dyed in one step with the same shade of red. A ribbon section already dyed with some shade of red can be overdyed with dyestuff of a darker shade; it is colored with that darker shade. Overdyeing with a lighter shade is, however, not allowed. As the ribbon is initially white, all the sections must be dyed at least once.
Figure A-1: Stripe Pattern of Sample Input 1
Figure A.1 shows the pattern of Sample Input 1. The ribbon has six sections and the numbers in the sections mean the levels of shades to be dyed. Larger numbers mean darker shades. This can be made by three dyeing steps:
- dye the entire ribbon with red dyestuff of shade level 50,
- dye the second section from the left with darker shade dyestuff of level 100, and then
- dye the fifth section with dyestuff of level 100.
Write a program that computes the least number of dyeing steps to make the planned stripe pattern.
Input
The input consists of a single test case of the following format.
| \(n\) |
|---|
| \(d_1\) \(d_2\) \(\cdots\) \(d_n\) |
The test case starts with an integer \(n\) \((1 \le n \le 100),\) the number of sections of the ribbon. The second line contains \(n\) integers, \(d_1, d_2, \ldots, d_n\), describing the planned shade levels of the \(n\) sections. Here, \(d_i\) means the planned shade level of the \(i\)-th section, which is between 1 and 100, inclusive, larger meaning darker.
Output
Output a line containing the least number of dyeing steps to make the planned stripe pattern.
题意:
给一个色带, 连续染色多个片段算一次, 深的颜色会覆盖浅的颜色, 问最少染色多少次?
朴素算法:
对于每一个点, 从他往后合并区块直到找到比它小的, 算作一次, 最后加起来。
#include<bits/stdc++.h>
using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned int;
using i128 = __int128;
#define TEST
#define TESTS int T; cin >> T; while(T--)
using namespace std;
void Main() {
int n;
cin >> n;
vector<int> d(n + 1), a(n + 1, 0);
for(int i = 1; i <= n; ++i) cin >> d[i];
int ans = 0;
for(int i = 1; i <= n; ++i) {
if(a[i] < d[i]) {
ans++;
for(int j = i; j <= n and d[j] >= d[i]; ++j) {
a[j] = d[i];
}
// for(int i = 1; i <= n; ++i) cout << a[i] << ' ';
// cout << endl;
}
}
cout << ans << endl;
}
signed main() {
ios :: sync_with_stdio(false);
cin.tie(0); cout.tie(0);
TEST Main();
return 0;
}
//其实就是模拟染色流程
也可以用栈:
其实就是维护单调栈
连续相同的不管,每当有更大的时就记一次(因为这个肯定要染一次),然后入栈。如果是小的就把栈里大于他的都出掉之后重来一遍。
有点不知道这个解法是怎么想出来的
#include<bits/stdc++.h>
using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned int;
using i128 = __int128;
#define TEST
#define TESTS int T; cin >> T; while(T--)
using namespace std;
void Main() {
int n;
cin >> n;
int ans = 0;
stack<int> st;
vector<int> d(n);
for(int i = 0; i < n; ++i) cin >> d[i];
for(int i = 0; i < n; ++i) {
if(!st.empty() and st.top() == d[i]) continue;
if(st.empty() or st.top() < d[i]) {
ans++;
st.push(d[i]);
}
if(!st.empty() and st.top() > d[i]) {
--i;
st.pop();
}
}
cout << ans << endl;
}
signed main() {
ios :: sync_with_stdio(false);
cin.tie(0); cout.tie(0);
TEST Main();
return 0;
}
我自己写的好像有点丑,网上找了一个板子
for(int i = 0; i < n; ++i) {
while(!st.empty() and st.top() > d[i]) st.pop();
if(!st.empty() and st.top() == d[i]) continue;
else {
ans++;
st.push(d[i]);
}
}

浙公网安备 33010602011771号