1584: [Usaco2009 Mar]Cleaning Up 打扫卫生
来源:互联网 发布:临淄广电网络客服电话 编辑:程序博客网 时间:2024/03/29 02:21
题目链接
题目大意:n个数,分成若干段,若该段中有k个不同的数,定义该段的费用k*k,求最小费用
题解:只会n^2……
观察到对于一个区间,其答案上界为len,也就是说区间内最多
记录pre[i]为i位置的数上次出现的位置,cnt[j]为[pos[j]+1,i]中不同数字个数
跪啊
我的收获:寻找答案上界奇妙优化,数学大法
#include <iostream>#include <cstring>#include <cstdio>#include <cmath>#include <algorithm>using namespace std;#define M 50005int n,m,a[M];int pos[M],cnt[M],f[M];int pre[M],nxt[M],last[M];void Dp(){ memset(f,0x3f,sizeof(f));f[0]=0; for(int i=1;i<=n;i++) { for(int j=1;j*j<=n;j++) if(pre[i]<=pos[j]) ++cnt[j];//a[i]上次位置不在[pos[j]+1,i]中,加入a[i] for(int j=1;j*j<=n;j++) if(cnt[j]>j)//超出范围 { pos[j]++;//移动左端点pos[j]+1,暴力移动pos(j),直到完全删掉1个数字,意会一下 while(nxt[pos[j]]<=i) pos[j]++;//均摊O(1) cnt[j]--; } for(int j=1;j*j<=n;j++) f[i]=min(f[i],f[pos[j]]+j*j);//转移 }}void work(){ Dp(); printf("%d\n",f[n]);}void init(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]),pre[i]=last[a[i]],last[a[i]]=i; memset(last,0,sizeof(last)); for(int i=n;i>=1;i--) nxt[i]=last[a[i]],last[a[i]]=i; for(int i=1;i<=n;i++) if(!nxt[i]) nxt[i]=n+1;//net数组注意赋值!! }int main(){ init(); work(); return 0;}
正常做法
实现的时候直接用双向链表删掉相同的位置,只保留最后一个
#include <iostream>#include <cstring>#include <cstdio>#include <cmath>#include <algorithm>using namespace std;#define M 50005int n,a[M];int pos[M],f[M];int pre[M],nxt[M];void del(int x){ nxt[pre[x]]=nxt[x]; pre[nxt[x]]=pre[x];}void Dp(){ memset(f,0x3f,sizeof(f));f[0]=0; for(int i=1;i<=n;i++) { if(!pos[a[i]]) pos[a[i]]=i; else del(pos[a[i]]),pos[a[i]]=i; int cnt=0; for(int j=pre[i];j!=-1;j=pre[j]){ cnt++; f[i]=min(f[i],f[j]+cnt*cnt); if(cnt*cnt>i) break; } }}void work(){ Dp(); printf("%d\n",f[n]);}void init(){ scanf("%d%*d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) pre[i]=i-1,nxt[i]=i+1; pre[0]=-1;}int main(){ init(); work(); return 0;}
阅读全文
0 0
- 1584: [Usaco2009 Mar]Cleaning Up 打扫卫生
- bzoj1584【Usaco2009 Mar】Cleaning Up 打扫卫生
- [bzoj1584] [Usaco2009 Mar]Cleaning Up 打扫卫生
- BZOJ 1584 [Usaco2009 Mar]Cleaning Up 打扫卫生 动态规划
- 【BZOJ1584】[Usaco2009 Mar]Cleaning Up 打扫卫生【DP】
- bzoj1584 [Usaco2009 Mar]Cleaning Up 打扫卫生 dp
- [BZOJ1584][Usaco2009 Mar]Cleaning Up 打扫卫生(dp+数学相关优化)
- bzoj 1584 Cleaning Up 打扫卫生 dp
- DP Cleaning Up 打扫卫生
- [Usaco2009 Mar]Cleaning Up
- BZOJ 1584 [Usaco2009 Mar] Cleaning Up
- bzoj3401[Usaco2009 Mar]Look Up 仰望
- [BZOJ3401] [Usaco2009 Mar]Look Up 仰望
- BZOJ 3401: [Usaco2009 Mar]Look Up 仰望
- bzoj 3401: [Usaco2009 Mar]Look Up 仰望
- bzoj3401 [Usaco2009 Mar]Look Up 仰望
- [bzoj3401][Usaco2009 Mar]Look Up 仰望
- 哪里有打扫卫生
- sqlserver 存储过程 try catch TRANSACTION (转)
- mysql 联表更新查询
- Django入门-2:创建第一个Django项目
- SwipeDelMenuLayout 条目侧滑 条目点击事件无效处理
- Linux iptables详解
- 1584: [Usaco2009 Mar]Cleaning Up 打扫卫生
- git
- 程序调试中的常见问题及解决方法
- OpenCV2编程手册笔记之 4.5反投影直方图以检测特定图像内容
- Java 加解密技术系列之 BASE64
- Servlet是线程安全的吗?
- C/C++ 调用 Lua 函数(非全局函数)
- 百度富文本ueditor使用 以及 与 Struts2 整合时出现的问题解决
- 存储过程中使用事务与try catch