2023 睿抗省赛本科组 RC-u5 相对成功与相对失败

279 阅读3分钟

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;
}