首页 > 其他分享 >fzu_noip 1036(磁盘碎片整理-Dp)

fzu_noip 1036(磁盘碎片整理-Dp)

时间:2022-10-25 10:31:31浏览次数:78  
标签:noip int fzu 区间 Jack 整理 include Dp size


磁盘碎片整理

时限:1s 内存:32M

★问题描述:

Jack最近在PS海报。海报所需各种素材不但让Jack头大,也让硬盘分区中的文件碎片越来越多,电脑的反应速度越来越慢。

烦恼的Jack决定好好整理一下磁盘的碎片。但是,为了体现高手风范,自负的Jack不喜欢系统自带的整理工具,决定自己编写一个,希望你帮他完成简单的第一遍整理。

因为不可移动的系统文件的分隔,Jack的N个文件,分为许多文件块,杂乱分布在M个长度不等的区间中。在第一遍整理时,只将每个区间中的碎片进行顺序改变,不跨区间移动。

因为在Jack完成的第二次整理时,将把M个区间依顺序连接成一个完整区间,希望整理完成后,零碎度越低越好。(若连接后的完整区间,文件块i与文件块i+1属于不同文件,则零碎度+1)。

例:

N=5 M=3

存储区间1:长度3 文件块[4,3,1]

存储区间2:长度4 文件块[2,1,4,4]

存储区间3:长度3 文件块[1,3,1]

第一次整理,第二次连接后:[1,3,4][4,4,2,1][1,1,3],零碎度为5

★数据输入:

第一行n m(1<=n<=10,1<=m<=10000),表示有n个文件,m个存储区间。

接下来m行,每行第一个整数为Li(0<Li<=50),表示存储区间i的长度。接下来Li个整数,分别表示该区间第j文件块所属文件。

★结果输出:

输出两次整理完成后,能达到的最小零碎度。


输入示例

输出示例

5 3

3 4 3 1

4 2 1 4 4

3 1 3 1

5

 


 

简单Dp,f[i][j]表示到第i块硬盘前面接j能取得的最大头尾连接数(开始那个默认与之前的连接),则


F[i][j]=| max(f[i][l[j]],f[i-1][k]+(b[i-1][l[j]]&&(k!=l[j]||pre_size==1))) (i>1)

答案为tot-max(f[m][k](0<=k<n)) tot为每个区间不同数字类数的总和


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<functional>
#include<cmath>
using namespace std;
#define MAXN (10)
#define MAXM (10000+10)
#define MAXLi (50)
int n,m;
bool b[MAXM][11];
int f[MAXM][11];
int l[MAXN];
int main()
{
// freopen("piece.in","r",stdin);
memset(b,0,sizeof(b));
memset(f,0,sizeof(f));
scanf("%d%d",&n,&m);
int ans=0,pre_size=0;
for (int i=1;i<=m;i++)
{
int li;
scanf("%d",&li);
for (int j=1;j<=li;j++) scanf("%d",&l[j]);
sort(l+1,l+li+1);
int size=unique(l+1,l+li+1)-(l+1);
ans+=size;
// cout<<size<<endl;
// for (int i=1;i<=size;i++) cout<<l[i]<<' ';cout<<endl;
for (int j=1;j<=size;j++)
b[i][l[j]]=1;
if (i==1)
{
for (int j=1;j<=size;j++)
f[1][l[j]]=1;
}
else
{
for (int j=1;j<=size;j++)
for (int k=0;k<n;k++)
if (b[i-1][k])
{
f[i][l[j]]=max(f[i][l[j]],f[i-1][k]+(b[i-1][l[j]]&&(k!=l[j]||pre_size==1)));
}
}
pre_size=size;
}
int p=0;
for (int j=0;j<n;j++) {p=max(p,f[m][j]); }
/*
for (int i=1;i<=m;i++)
{
for (int j=0;j<n;j++)
cout<<f[i][j]<<' ';
cout<<endl;
}
*/
cout<<ans-p<<endl;
// while (1);
return 0;
}




标签:noip,int,fzu,区间,Jack,整理,include,Dp,size
From: https://blog.51cto.com/u_15724837/5794118

相关文章

  • fzu_noip 1033 (作业问题-拼最大的2,3,5倍数)
    作业问题时限:1s内存:32M★问题描述:小T很喜欢数学,每天老师刚布置完作业,他就开始思考,今天他遇到了困难。现在有很多的数字,你的任务是找出由这些数字组成的最大的数,并且这个数......
  • fzu_noip 1039(盖楼-线段树)
    盖楼时限:1s内存:32M★问题描述:S举办了一场盖楼比赛,有n位选手参赛,将这n位选手编号为1到n。比赛刚开始时第i位选手的房子的初始高度为Ai,每过一天该选手的房子高度增加Bi。S想......
  • BZOJ 1084([SCOI2005]最大子矩阵-长矩阵Dp)
    1084:[SCOI2005]最大子矩阵TimeLimit: 10Sec  MemoryLimit: 162MBSubmit: 586  Solved: 275[​​Submit​​][​​Status​​][​​Discuss​​]De......
  • 如何用界面组件DevExpress WinForm创建一个支持High DPI的应用?
    DevExpressWinForm拥有180+组件和UI库,能为WindowsForms平台创建具有影响力的业务解决方案。DevExpressWinForms能完美构建流畅、美观且易于使用的应用程序,无论是Office......
  • Java多线程(3):ThreadPool(中)
    您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来~ 线程池是个神器,用得好会非常地方便。本来觉得线程池的构造器有些复杂,即使讲清楚了对今后的用处可能也不太大,因为有一些J......
  • ACSX 10 月专题训练:DP
    FreeMarkethttps://www.luogu.com.cn/problem/CF364B一个观察是第一个限制是无用的,原因在于你拿去的如果跟它有交你就只换没交的部分就行了。所以你手上一个总权值为X......
  • P2015 二叉苹果树 (树形DP)
    二叉苹果树题目描述有一棵苹果树,如果树枝有分叉,一定是分二叉(就是说没有只有一个儿子的结点)这棵树共有\(N\)个结点(叶子点或者树枝分叉点),编号为\(1\simN\),树根编号......
  • 【luogu AGC035E】Develop(分类讨论)(DP)
    Develop题目链接:luoguAGC035E题目大意一开始有-1e18~1e18的所有整数,然后你每次操作可以在1~N中选一个还在的数x,擦掉他,然后查看x-2,x+K,如果没有就把数加上。然后......
  • 洛谷上扒的DP练习题
    DP综述最优子结构:把原问题化到规模更小的问题后,原问题的最优解一定能从规模更小问题的最优解推出。无后效性:如果在某个阶段上过程的状态已知,则从此阶段以后过程的发展变......
  • P1880 [NOI1995] 石子合并 (区间DP)
    [NOI1995]石子合并题目描述在一个圆形操场的四周摆放\(N\)堆石子,现要将石子有次序地合并成一堆,规定每次只能选相邻的\(2\)堆合并成新的一堆,并将新的一堆的石子数,记......