zoukankan      html  css  js  c++  java
  • 洛谷 P1777 帮助_NOI导刊2010提高(03) 解题报告

    P1777 帮助_NOI导刊2010提高(03)

    题目描述

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

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

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

    输入输出格式

    输入格式:

    最多会有20组测试数据。每组测试数据开头为两个整数n,k(l≤k≤n≤100),表示总共有n本书,最多可以进行k次搬书操作。接下来一行有n个整数,表示每本书的高度,从左到右。每本书的高度是25到32间的整数。最后一组数据后有一行n=k=0。

    输出格式:

    对于每一组数据,输出Case标号和最终最小的混乱度。在每组数据后打印一个空行。


    我们发现,对于拿出去的书是可以随便放的,因为我们可以最后处理它们。

    很显然要做DP,顺序可以直接从左到右,满足无后效性。需要最后一个书的编号,以便后面使用。当然取出了几本也得压进状态。

    为了处理拿出去的书,我们得把书的状态集合给存储下来。因为拿出去的书拿走以后,可能在原书架里面没有了,最后要根据状态放回来。

    方程:
    (dp[i][j][sta][l])表示(i)位置第(j)次换书之前的书的状态集合为(sta)当前书的集合最后一本为(l)


    Code:

    #include <cstdio>
    #include <cstring>
    const int N=104;
    const int inf=0x3f3f3f3f;
    int min(int x,int y){return x<y?x:y;}
    int dp[2][N][1<<10][10],n,k,r,a[N];
    void DP()
    {
        for(int i=1;i<=n;i++)//位置
        {
            memset(dp[i&1],0x3f,sizeof(dp[i&1]));
            for(int j=0;j<=min(k,i);j++)//拿走了几个
                for(int sta=0;sta<(1<<r);sta++)//前面的状态,这个没填
                    for(int l=0;l<=r;l++)//末尾书本
                        if(!l||(sta>>l-1)&1)
                        {
                            dp[i&1][j][sta|(1<<a[i]-1)][a[i]]=min(dp[i&1][j][sta|(1<<a[i]-1)][a[i]]
                                                               ,dp[i-1&1][j][sta][l]+(l!=a[i]));//不拿
                            if(j)
                                dp[i&1][j][sta][l]=min(dp[i&1][j][sta][l],dp[i-1&1][j-1][sta][l]);//拿走
                        }
        }
    }
    int cal(int x)
    {
        int cnt=0;
        while(x)
        {
            cnt++;
            x-=x&-x;
        }
        return cnt;
    }
    int main()
    {
        scanf("%d%d",&n,&k);
        int cnt=0;
        while(n&&k)
        {
            int sta=0;
            r=0;cnt++;
            for(int i=1;i<=n;i++)
            {
                scanf("%d",a+i);
                a[i]-=24;
                r=r>a[i]?r:a[i];
                sta|=1<<a[i]-1;
            }
            memset(dp[0],0x3f,sizeof(dp[0]));
            dp[0][0][0][0]=0;
            DP();
            int ans=inf;
            for(int i=1;i<=k;i++)
                for(int j=0;j<(1<<r);j++)
                    for(int l=1;l<=r;l++)
                        if(dp[n&1][i][j][l]!=inf)
                            ans=min(ans,dp[n&1][i][j][l]+cal(sta-j));
            printf("Case %d: %d
    
    ",cnt,ans);
            scanf("%d%d",&n,&k);
        }
        return 0;
    }
    
    

    2018.7.6

  • 相关阅读:
    信用风险评分卡研究-第7章笔记
    信用风险评分卡研究-第6章笔记
    信用风险评分卡研究-第5章
    CSS3新特性
    H5相关知识点整理
    css3实现立体魔方效果
    后台管理系统基本布局
    react路由初探(2)
    react路由初探(1)
    将一个数组转化为需要的格式,来自react官网的商品列表示例
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9275523.html
Copyright © 2011-2022 走看看