• 【BZOJ1226】学校食堂(动态规划,状态压缩)


    【BZOJ1226】学校食堂(动态规划,状态压缩)

    题面

    BZOJ
    洛谷

    题解

    发现(b)很小,意味着当前这个人最坏情况下也只有后面的一小部分人在他前面拿到饭。
    所以整个结果的大致顺序是不会变化的。
    对于一个人,他要占用的时间之和前面那个拿饭的人有关。
    而他前面那个拿饭的人在队列中只有两种情况,一种在他前面,一种在他后面。
    显然在他前面对于当前这个人是没有任何影响的,有问题的只有在他后面的人先拿饭。
    所以可以状压后面哪些人在当前这个人之前拿到了饭。
    所以设状态(f[i][j][k])表示当前第(i)个人,(i)和后面(b)个人拿饭的情况是(j),上一个拿饭的人是(i+k),并且(i)之前的所有人都拿到了饭的最小值。
    注意一下(k)的值域范围([-8,7])
    考虑转移
    首先检查一下当前这个位置是否已经被解决。
    如果是,直接转移到(f[i+1][j>>1][k-1])(k-1)的原因是向后推了一位。
    否则,枚举当前解决谁,计算一下贡献就好了。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define RG register
    #define MAX 1010
    #define cmin(a,b) (a=((a>b)?(b):(a)))
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    int f[MAX][1<<8][17],n,a[MAX],b[MAX],ans;
    int calc(int i,int j){if(!i)return 0;return a[i]^a[j];}
    int main()
    {
    	int T=read();
    	while(T--)
    	{
    		n=read();ans=1e9;
    		for(int i=1;i<=n;++i)a[i]=read(),b[i]=read();
    		memset(f,63,sizeof(f));f[1][0][-1+8]=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]>=1e9)continue;
    					if(j&1)cmin(f[i+1][j>>1][k+7],f[i][j][k+8]);
    					else
    					{
    						int lst=1e9;
    						for(int l=0;l<=7;++l)
    						{
    							if(i+l>lst)break;if(j&(1<<l))continue;
    							cmin(lst,b[i+l]+i+l);
    							cmin(f[i][j|(1<<l)][l+8],f[i][j][k+8]+calc(k+i,l+i));
    						}
    					}
    				}
    		for(int i=0;i<=8;++i)cmin(ans,f[n][1][i]);
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    交叉编译OpenCV的教程——基于aarch64-linux-gnu的交叉编译器
    Day01:我的Python学习之路
    将中文库导入到ARM板子中以解决中文显示乱码的教程
    Linux环境下挂载SD卡的教程
    Ubuntu下压缩与解压各种文件的命令
    Ubuntu14.04环境下Qt5.5以上版本无法输入中文的解决教程
    编程之美:队列中的最大最小值
    leetcode:Compare Version Numbers
    leetcode:Search for a Range
    csapp:无符号数可能造成的程序bug
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9308885.html
Copyright © 2020-2023  润新知