zoukankan      html  css  js  c++  java
  • P1777 帮助_NOI导刊2010提高(03)

    也许更好的阅读体验

    (mathcal{Description})

    Bubu的书架乱成一团了!帮他一下吧!

    他的书架上一共有n本书。我们定义混乱值是连续相同高度书本的段数。例如,如果书的高度是30,30,31,31,32,那么混乱值为3,30,32,32,31的混乱度也是3,但31,32,31,32,31的混乱度是5,这实在是太乱了。

    Bubu想尽可能地减少混乱度,但他有点累了,所以他决定最多取出k本书,再随意将它们放到书架上。你能帮助他吗?

    (mathcal{Solution})

    考虑取出一本书把其认为是删掉这本书,因为总有办法使其不会影响到后面的取书过程
    特殊的是如果将一种书全部删掉,那么应该还是会有1的混乱度
    如果考虑(dp)方式为如何删书,那么这个过程实在复杂
    如果考虑最后剩下的书,那么复杂度是(2^n)妥妥的(T)
    但是仔细的想一下,会发现,考虑最后剩下的书时,并不是前面所有的状态都对现在的状态会有影响
    即如果一本书隔得较远,则与你当前这本书没有多大关系,在保证所有的状态会被考虑在内的情况下,考虑状态压缩
    (f[i][j][s][l])表示前(i)本书,删掉了(j)本,剩下书的种类的集合为(s),上一本没有被删的书的种类是(l)

    考虑第(i)本书

    • 若删掉这本书,则有(f[i][j+1][s][l]=minleft(f[i][j][s][l],]f[i-1][j][s][l] ight))
    • 若保留这本书,则有(f[i][j][s|(1<<h[i])][h[i]]=minleft(f[i][j][s|(1<<h[i])][h[i]],f[i-1][j][s][l]+left(h[i]==l?0:1 ight) ight))

    最后的时候回来考虑剩下的书的种类集合,如果原本所有书的种类集合(S)有一种书,现在没有了,那么我们就多减了一个1,加回来就是

    (mathcal{Code})

    /*******************************
    Author:Morning_Glory
    LANG:C++
    Created Time:2019年10月04日 星期五 08时36分03秒
    *******************************/
    #include <cstdio>
    #include <fstream>
    #include <algorithm>
    #include <cstring>
    #define inf 0x7f7f7f7f
    using namespace std;
    const int maxn = 111;
    const int lim = 256;
    //{{{cin
    struct IO{
    	template<typename T>
    	IO & operator>>(T&res){
    		res=0;
    		bool flag=false;
    		char ch;
    		while((ch=getchar())>'9'||ch<'0')	flag|=ch=='-';
    		while(ch>='0'&&ch<='9')	res=(res<<1)+(res<<3)+(ch^'0'),ch=getchar();
    		if (flag)	res=~res+1;
    		return *this;
    	}
    }cin;
    //}}}
    int n,k,cas;
    int h[maxn],one[lim+5];
    int f[2][maxn][lim+5][11];
    bool now,pre;
    //f[i][j][k][l] 前i本书选了j本书,存在的书的种类集合为k,上一本书为l
    int main()
    {
    	for (int i=0;i<lim;++i){
    		for (int j=0;j<8;++j)
    			if (i&(1<<j))	++one[i];
    	}
    	while (true){
    		cin>>n>>k;
    		if (n+k==0)	break;
    		int S=0,mh=0;
    		for (int i=1;i<=n;++i){
    			cin>>h[i];
    			h[i]-=25;
    			S|=1<<h[i];
    			mh=max(mh,h[i]);
    		}
    		++mh;
    		memset(f[0],0x7f,sizeof(f[0]));
    		now=0;
    		f[0][0][1<<h[1]][h[1]]=1;
    		f[0][1][0][mh]=0;
    		for (int i=2;i<=n;++i){
    			now^=1,pre=!now;
    			memset(f[now],0x7f,sizeof(f[now]));
    			for (int j=0;j<=k;++j){
    				for (int s=0;s<=S;++s)
    					for (int l=0;l<=mh;++l)
    						if (f[pre][j][s][l]!=inf){
    							f[now][j][s|(1<<h[i])][h[i]]=min(f[now][j][s|(1<<h[i])][h[i]],f[pre][j][s][l]+(h[i]==l?0:1));
    							f[now][j+1][s][l]=min(f[now][j+1][s][l],f[pre][j][s][l]);
    						}
    			}
    		}
    		int ans=inf;
    		for (int j=0;j<=k;++j)
    			for (int s=0;s<=S;++s)
    				for (int l=0;l<mh;++l)
    					if (f[now][j][s][l]!=inf){
    						int take=S^s;
    						ans=min(ans,f[now][j][s][l]+one[take]);
    					}
    		printf("Case %d: %d
    
    ",++cas,ans);
    	}
    	return 0;
    }
    
    

    如有哪里讲得不是很明白或是有错误,欢迎指正
    如您喜欢的话不妨点个赞收藏一下吧

  • 相关阅读:
    JavaScript Web页面内容导出到Word、Excel (转载)
    合并多个声音文件
    龙舟记
    c#获取应用程序目录
    ADO.NET数据库连接池研究(一) 查看连接池数 (转)
    UpdatePanel 内控件 更新“外的”控件【转】
    web客户端播放wav文件
    解决DataList控件无缝滚动图片(转)
    关闭sleeping连接进程在Sql Server2000数据库存储过程中(转)
    win7下没有注册类别 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG))
  • 原文地址:https://www.cnblogs.com/Morning-Glory/p/11623293.html
Copyright © 2011-2022 走看看