【洛谷p2837】晚餐队列安排

时间:2022-08-04 04:15:16

(一定要先贴一下wz大佬对这道题的定位:【洛谷p2837】晚餐队列安排

另外说一句:我终于在拖了nnnnnnnnn天之后做完了这道题

算法标签:(其实也用不到辽上面都有)但我就是要贴一下咬我啊)

【洛谷p2837】晚餐队列安排


好啦好啦,上

  • 思路:

首先为了节省空间,我令1=>0     2=>1;开了一个二维数组f[i][1/0](为什么开f呢,因为发)用f[i][1]代表第i项为2时需要改动的最小个数,用f[i][0]表示第i项为1时需要改动的最小个数。这样形成递推:

for(int i=;i<=n;i++)
{
if(a[i]==){//第i个数为1时
            f[i][]=f[i-][];//如果不改动这个数,
那么最小值就等于上一个数为1时的值
f[i][]=min(f[i-][],f[i-][])+;//若改为2,那么前面的i-1个数
可以选择全置为1或全置为2,取两个中最小的,
再加上改动的1
}
if(a[i]==){//第i个数为2时
f[i][]=min(f[i-][],f[i-][]);//保持第i个数为2,则前i-1个数可以全为1
也可以全为2,取其中较小的,赋给f[i][1];
f[i][]=f[i-][]+;//改变第i个数为1,那么前面必须全为1,
那么f[i][0]就为f[i-1][0]+1;
}
}

最后求出f[n][1]和f[n][0],比较他们的值,选择较小的一个输出

  • 代码:(赶脚好low哦
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
using namespace std;
int n,a[];//我也不知道为啥要开这么大,好看
int f[][];
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
f[][-a[]]=;
f[][a[]-]=;
for(int i=;i<=n;i++)
{
if(a[i]==){
f[i][]=f[i-][];
f[i][]=min(f[i-][],f[i-][])+;
}
if(a[i]==){
f[i][]=min(f[i-][],f[i-][]);
f[i][]=f[i-][]+;
}
}
int ans=min(f[n][],f[n][]);
printf("%d",ans);
}

end-