博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ1609 [Usaco2008 Feb]Eating Together麻烦的聚餐
阅读量:4600 次
发布时间:2019-06-09

本文共 1310 字,大约阅读时间需要 4 分钟。

题目大意:把一个只含1,2,3的序列改成形如111……222……333……或333……222……111……的形式最少改几个数。

题解:光看这个数列无从知晓答案,所以试着采用DP。由于每个数变1,2,3与后面的数怎么变密切相关,所以F[i][j]表示前i个数中,第i个数变j后满足第一种形态的最少次数,则有F[i][j]=F[i-1][k]+diff(a[i],j),其中k∈[1,j],diff(a,b)表示a,b是否不同。形态2的话,既可以把上式的“i-1”改为“i+1”,又可以把整个序列前后颠倒再搞一次,非常自由。

代码:

#include
#include
#include
#include
#include
using namespace std;int qread(){ char c;int s=0; while (!isdigit(c=getchar())); do {s=s*10+c-'0';} while (isdigit(c=getchar())); return s;}int n;#define maxn 30233int a[maxn],f[maxn][5];#define inf 0x7fffffffint dif(int x,int y){ return (x==y?0:1);}void solve(){ for (int j=1;j<=3;j++) f[0][j]=0; for (int i=1;i<=n;i++) for (int j=1;j<=3;j++) { f[i][j]=inf; int d=dif(a[i],j); for (int k=j;k;k--) f[i][j]=min(f[i][j],f[i-1][k]+d); }}int main(){ n=qread(); for (int i=1;i<=n;i++) a[i]=qread(); solve(); int ans1=min(f[n][1],min(f[n][2],f[n][3])); for (int i=1;i<=n/2;i++) {
int t=a[i];a[i]=a[n-i+1];a[n-i+1]=t;} solve(); int ans2=min(f[n][1],min(f[n][2],f[n][3])); printf("%d\n",min(ans1,ans2)); return 0;}
View Code

 

转载于:https://www.cnblogs.com/Blue233333/p/6159128.html

你可能感兴趣的文章
Firefox的缓存问题
查看>>
ENSP错误
查看>>
Java MVC 分页实例
查看>>
响应式布局1--媒体查询和-webkit-min-device-pixel-ratio
查看>>
CocoaPods应用于iOS项目框架管理方案
查看>>
POJ-3233 Matrix Power Series 矩阵A^1+A^2+A^3...求和转化
查看>>
IIS是如何处理ASP.NET请求的
查看>>
SSIS之Foreach循环容器应用
查看>>
局域网内访问机器时出现“未授予在次计算机上的请求登陆类型”
查看>>
硬币组合问题
查看>>
(9)模板层 - templates(模板语言、语法、取值、过滤器、变量的使用)
查看>>
P3469 [POI2008]BLO-Blockade
查看>>
P1171 售货员的难题
查看>>
DevOps之持续交付
查看>>
有趣的数学(一)
查看>>
迟来的2013年总结及算法工程师/研究员找工作总结
查看>>
java面向对象中的关键字
查看>>
网络类型IPv4和IPv6什么意思?区别?
查看>>
6周学习计划,攻克JavaScript难关(React/Redux/ES6 etc.)
查看>>
大对象堆及.NET垃圾回收器的改进
查看>>