分析:遇到s1尽量穿普通衣服,普通t没有了就穿标志t,标志t也没了就要买一件。
遇到s2必须穿标志t,没有了就买一件。
最少买多少件,取决与两个s0天之间的日子,要买多少件t
void solve() {
int n, m; cin >> n >> m;
string s; cin >> s;
int pm = m;
int cnt = 0;
int pc = 0;
for (int i = 0; i < s.size(); i++) {
if (s[i] == '1') {
if (pm == 0) {
if (pc == 0) {
cnt++;
}
else {
pc--;
}
}
else {
pm--;
}
}
else if (s[i] == '2') {
if (pc == 0) {
cnt++;
}
else {
pc--;
}
}
else {
pc = cnt; pm = m;
}
}
cout << cnt;
}
分析:关注一下数据量,特别特别小,因此可以用暴力dfs枚举所有情况,但是我太菜了,dfs写不明白,如果大佬有dfs解法可以在评论区留言。所以这里用next_permutation全排列函数来枚举所有情况,效果和自己手写dfs的效果是一样的。
1)两个数组,r和c数组,r
和 c
分别表示数组a的行和列的索引,用来存行和列变换的状态。一会nex_permutation就是对这两个数组操作,枚举所有行和列变换的情况。
2)如果经过变换后的a等于b(注意,不是真的对数组a进行变换,而是变换了r和c数组实现“伪变换”,因为变换r和c数组后,我们就可以知道变换后的a的样子),我们就去算a变换了多少次。
逆序对的个数就是变换次数,这里不证明了。
ps:要注意行和列都只能和相邻的交换!当时就是题目没看清浪费了很多时间
int a[10][10], b[10][10]; int n, m;
int r[6] = { 0,1,2,3,4,5 };
int c[6] = { 0,1,2,3,4,5 };
bool check(int e1[10][10],int e2[10][10]) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (e1[i][j] != e2[i][j]) return false;
}
}
return true;
}
void solve() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> a[i][j];
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> b[i][j];
}
}
int ans = inf;
//注意是相邻交换!
do {//用do-while是因为,可能一次也不变换
do {
if (check(a, b)) {
int num = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (i<j && r[i]>r[j]) {
num++;
}
}
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= m; j++) {
if (i<j && c[i]>c[j]) {
num++;
}
}
}
ans = min(ans, num);
}
} while (next_permutation(c + 1, c + 1 + m));
} while (next_permutation(r + 1, r + 1 + n));
//tans;
if (ans == inf) cout << -1 << endl;
else cout << ans << endl;
}
最后附上next_permutation的用法
next_permutation 是 C++ STL 中的一个函数,用于求一个序列的下一个排列。下面是它的基本用法:
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> v{1, 2, 3};
do {
for (auto i : v) {
std::cout << i << ' ';
}
std::cout << '\n';
} while (std::next_permutation(v.begin(), v.end()));
return 0;
}
这段代码会输出 1 2 3、1 3 2、2 1 3、2 3 1、3 1 2、3 2 1 这六个排列。
next_permutation 的参数是一个迭代器区间,表示一个序列。它返回值是一个 bool 类型,表示是否找到了序列的下一个排列。如果找到了下一个排列,则函数会直接修改原序列。
如果想按照自定义排序规则来求下一个排列,可以使用自定义比较函数。比如,将上面的代码改为按照字典序升序排列:
#include <algorithm>
#include <iostream>
#include <vector>
bool my_compare(int a, int b) {
return a > b;
}
int main() {
std::vector<int> v{3, 2, 1};
do {
for (auto i : v) {
std::cout << i << ' ';
}
std::cout << '\n';
} while (std::next_permutation(v.begin(), v.end(), my_compare));
return 0;
}