RC-u5 相对成功与相对失败 - 2023 睿抗机器人开发者大赛CAIP-编程技能赛-本科组(省赛) (pintia.cn)
题解: 2023 睿抗机器人开发者大赛CAIP-编程技能赛-本科组(省赛)_2023睿抗caip编程设计赛道省赛 csdn-CSDN博客
状态表示
集合
dp[i][j]表示到第i名为止,状态编号为j时不发生冲突,此时最少说谎的人数为多少.
状态0
我们定义状态0为参加比赛不玩手机
状态1
定义状态1为参加比赛玩手机/不参加比赛不玩手机 (这两种价值一样)
状态2
定义状态2为不参加比赛玩手机
pos[i]表示第i名选手的状态是否冲突(即是否说谎). 为0表示没有说谎,为1表示说谎
如果第i名选手是状态1(参加比赛不玩手机),那么他前面的选手的状态必然也是状态0(前面的选手要比他更成功,但状态0已经是最高状态). pos1标注他是否撒谎.
dp[i][0]=dp[i-1][0]+pos1;
如果第i名选手是 参加比赛玩手机的状态 /不参加比赛不玩手机的状态,那么他前面的选手的状态必须是参加比赛不玩手机的状态/参加比赛玩手机的状态/不参加比赛不玩手机的状态.
pos1,pos2/pos3来标注他是否撒谎
dp[i][1]=min(dp[i-1][0],dp[i-1][1])+min(pos2,pos3);
如果第i名选手的状态是不参加比赛不玩手机的状态1,那么他前面的选手的状态必须是状态0/状态1/状态2
用pos1,pos2,pos3,pos4来标注他是否撒谎.
dp[i][2]=min((dp[i-1][0],dp[i-1][1]),dp[i-1][2])+pos4;
属性
min()
code
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 100;
struct
{
int f1, f2;
}a[N];
int r[N];
int dp[N][3];
void solve()
{
int n; cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i].f1 >> a[i].f2;
}
for (int i = 1; i <= n; i++)
{
cin >> r[i];
dp[i][0] = dp[i - 1][1] = dp[i - 1][2] = 1e6 + 100; //因为求最小撒谎 ,初始化为最大
}
for (int i = 1; i <= n; i++)
{
int pos1 = 1, pos2 = 1, pos3 = 1, pos4 = 1; //全部初始化1为撒谎
int x = r[i];
if (a[x].f1 == 1 && a[x].f2 == 0) pos1 = 0;
if (a[x].f1 == 1 && a[x].f2 == 1) pos2 = 0;
if (a[x].f1 == 0 && a[x].f2 == 0) pos3 = 0;
if (a[x].f1 == 0 && a[x].f2 == 1) pos4 = 0;
dp[i][0] = dp[i - 1][0] + pos1;
dp[i][1] = min(dp[i - 1][0], dp[i - 1][1]) + min(pos2, pos3);
dp[i][2] = min(min(dp[i - 1][0], dp[i - 1][1]), dp[i - 1][2]) + pos4;
}
int ans = 1e6 + 100;
for (int i = 0; i <= 2; i++)
{
ans = min(ans, dp[n][i]);
}
cout << ans << endl;
}
int main()
{
int t; cin >> t;
while (t--)
{
solve();
}
return 0;
}#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 100;
struct
{
int f1, f2;
}a[N];
int r[N];
int dp[N][3];
void solve()
{
int n; cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i].f1 >> a[i].f2;
}
for (int i = 1; i <= n; i++)
{
cin >> r[i];
dp[i][0] = dp[i - 1][1] = dp[i - 1][2] = 1e6 + 100; //因为求最小撒谎 ,初始化为最大
}
for (int i = 1; i <= n; i++)
{
int pos1 = 1, pos2 = 1, pos3 = 1, pos4 = 1; //全部初始化1为撒谎
int x = r[i];
if (a[x].f1 == 1 && a[x].f2 == 0) pos1 = 0;
if (a[x].f1 == 1 && a[x].f2 == 1) pos2 = 0;
if (a[x].f1 == 0 && a[x].f2 == 0) pos3 = 0;
if (a[x].f1 == 0 && a[x].f2 == 1) pos4 = 0;
dp[i][0] = dp[i - 1][0] + pos1;
dp[i][1] = min(dp[i - 1][0], dp[i - 1][1]) + min(pos2, pos3);
dp[i][2] = min(min(dp[i - 1][0], dp[i - 1][1]), dp[i - 1][2]) + pos4;
}
int ans = 1e6 + 100;
for (int i = 0; i <= 2; i++)
{
ans = min(ans, dp[n][i]);
}
cout << ans << endl;
}
int main()
{
int t; cin >> t;
while (t--)
{
solve();
}
return 0;
}