Eating Together(dp)

Eating Together(dp)

链接:https://ac.nowcoder.com/acm/contest/997/G
来源:牛客网
链接:https://ac.nowcoder.com/acm/contest/997/G
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

The cows are so very silly about their dinner partners. They have organized themselves into three groups (conveniently numbered 1 , 2 , 1, 2, 1,2, and 3 3 3) that insist upon dining together. The trouble starts when they line up at the barn to enter the feeding area.
Each cow i carries with her a small card upon which is engraved D D Di ( 1 ≤ D (1 ≤ D (1Di ≤ 3 ) ≤ 3) 3) indicating her dining group membership. The entire set of N ( 1 ≤ N ≤ 30 , 000 ) N (1 ≤ N ≤ 30,000) N(1N30,000) cows has lined up for dinner but it’s easy for anyone to see that they are not grouped by their dinner-partner cards.
FJ’s job is not so difficult. He just walks down the line of cows changing their dinner partner assignment by marking out the old number and writing in a new one. By doing so, he creates groups of cows like 111222333 111222333 111222333 or 333222111 333222111 333222111 where the cows’ dining groups are sorted in either ascending or descending order by their dinner cards.
FJ is just as lazy as the next fellow. He’s curious: what is the absolute mminimum number of cards he must change to create a proper grouping of dining partners? He must only change card numbers and must not rearrange the cows standing in line.

输入描述:

  • Line 1: A single integer: N N N
  • Lines 2… N + 1 N+1 N+1: Line i describes the i − t h i-th ith cow’s current dining group with a single integer: D D Di

输出描述:

  • Line 1: A single integer representing the minimum number of changes that must be made so that the final sequence of cows is sorted in either ascending or descending order

题意

FJ的工作并不难。他只是沿着牛的路线走,通过标出旧的数字并用新的数字来改变他们的晚餐搭档的任务。通过这样做,他创建了一组奶牛,如111222333或333222111,在那里,奶牛的用餐组按晚餐卡的升序或降序排序。

FJ和其他人一样懒惰。他很好奇:为了创建一个合适的用餐伙伴群体,他必须更改的卡的绝对最小数量是多少?

输出一个整数,表示必须进行的最小更改数,以便将奶牛的最终序列按升序或降序排序

样例说明:我们至少需要两次更改才能将其转换为递增序列(将非1的两个都更改为1)。
但是,将第一个“1”更改为“3”会产生一个只有一个更改的递减序列,这是最佳的。

示例1

输入

5
1
3
2
1
1

输出

1

说明

We would need at least two changes to turn this into an increasing sequence (changing both non-1’s to a 1).
However, changing the first “1” to a “3” yields a decreasing sequence with just one change, which is optimal.

思路

很明显的一点就是求最长递增子序列和最长递减子序列
然后比较哪个更长
不过一般写法会超时,再看一下发现卡片编号只有1,2,3
这时候只需要记录以这个编号结尾的最长序列的长度
每次枚举只是把比当前编号小于等于/大于等于的编号结尾的序列连接过来。时间是O(3N)

代码

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 30005
#define inf 0x3f3f3f3f
#define _for(i, a) for(int i = 0; i < (a); i++)
#define _rep(i, a, b) for(int i = (a); i <= (b); i++)
int main() {
	int n;
	cin >> n;
	int num[2][3] = { 0 };
	int id;
	cin >> id;
	num[0][id - 1] = num[1][id - 1] = 1;
	for (int i = 1; i < n; i++) {
		cin >> id;
		int tem = -inf;
		_for(j, id) {
			tem = max(tem, num[0][j] + 1);
		}
		num[0][id - 1] = tem;
		tem = -inf;
		_rep(j, id - 1, 2) {
			tem = max(tem, num[1][j] + 1);
		}
		num[1][id - 1] = tem;
	}
	int ans = -inf;
	_for(i, 2) {
		_for(j, 3) {
			ans = max(ans, num[i][j]);
		}
	}
	cout << n - ans << "\n";
	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值