zoukankan      html  css  js  c++  java
  • [题解]luogu_P2157学校食堂(状压dp

    n个人排队打饭,每个人可以容忍在他后面的b[i]个人在他前面打饭,每次打饭的时间消耗为两个人权值异或(或-与),问最短时间

    小数据范围一定要想状压,b[i]<=7提示我们状压当前这个人周围的7个(左右)的人,要算每次消耗的时间还要再记上一个打饭的人,注意这个人不可能在某人后面或前面7位以上,所以直接记这个人和当前人的相对位置即可

    所以$f[i][j][k]$表示前$i-1$个人打完饭,$i~i+7$个人的状态为j,上一个打饭的人为$i+k(-8<=k<=7)$的最小花费,k可负要加偏移量(文中均未加偏移量

    然后想转移,无非是枚举下一个人是谁,但是如果i打过饭了那么i+1也可以更新了,不要再在i处更新了,即如果$(j&1),f[i+1][j>>1][k-1]=min(f[i+1][j>>1][k-1],f[i][j][k])$,可以看出这两个状态等价

    如果$!(j&1)$,就枚举下一个人$i+h(0<=h<=7)$,但是注意每个人都有限制,不妨从小到大枚举h,这样限制h的人会越来越多,一旦不合法直接break,很方便

    答案为$max(f[n+1][0][k])(-8<=k<=0)$,

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1009;
    const int inf=0x3f3f3f3f;
    int n,T,t[maxn],b[maxn];
    int f[maxn][1<<8][20];//1~i-1已打完 i~i+7打饭状态为s 上一个打饭的为i+k 
    int main(){scanf("%d",&T);
        while(T--){
            memset(f,0x3f,sizeof(f));
            scanf("%d",&n);
            for(int i=1;i<=n;i++)scanf("%d%d",&t[i],&b[i]);
            f[1][0][7]=0;//前0个人打完饭上一个打饭的是0消耗为0 
            for(int i=1;i<=n;i++){
                for(int j=0;j<(1<<8);j++)
                for(int k=-8;k<=7;k++)
                if(f[i][j][k+8]!=inf){
                    if(j&1)f[i+1][j>>1][k+7]=min(f[i+1][j>>1][k+7],f[i][j][k+8]);
                    else{
                        int lmt=inf;
                        for(int h=0;h<=7;h++)
                        if(!((j>>h)&1)){
                            if(i+h>lmt)break;
                            lmt=min(lmt,i+h+b[i+h]);//对于往后枚举h lmt会被更多人限制 所以可以这么推 
                            f[i][j|(1<<h)][h+8]=min(f[i][j|(1<<h)][h+8],f[i][j][k+8]+(i+k?(t[i+k]^t[i+h]):0));
                        }
                    }
                }
            }
            int ans=inf;
            for(int i=0;i<=8;i++)
            ans=min(ans,f[n+1][0][i]);
            printf("%d
    ",ans);
        }
    }
  • 相关阅读:
    搭建elk的坑
    mail发邮件报错 "send-mail: fatal: parameter inet_interfaces: no local interface found for ::1"
    shell脚本排坑
    rocketmq双主发送消息 SLAVE_NOT_AVAILABLE 状态
    基于mysql的基准测试
    mysql服务器参数
    MySql Host is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts' 解决方法
    mysql存储引擎
    zabbix安装
    iostat查看系统的IO负载情况
  • 原文地址:https://www.cnblogs.com/superminivan/p/11656628.html
Copyright © 2011-2022 走看看