拯救莫莉斯题解

Posted ljk123-de-bo-ke

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了拯救莫莉斯题解相关的知识,希望对你有一定的参考价值。

拯救莫莉斯题解

实际上是水题啦,
观察数据发现,(m*n<=50,m<=n),所以(m<=sqrt(50))(m<=7)
只可能是状压啊,搜索啊,矩阵啊
但是矩阵一般有一项非常大,大到(O(n))做不了,所以基本排除,
搜索基本不可能的,毕竟吗m*n还是有50的,
所以状压,
水啊,
上代码吧:

#include<bits/stdc++.h>
using namespace std;
const int N=56,M=147;
int n,m,t,p,g[N][M],f[N][M][M],q[N][M][M],o[M],ans1=2e9,ans2=2e9;
inline int read(){
   int T=0,F=1; char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();}
   while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar();
   return F*T;
}
int main(){
    n=read(),m=read(),p=(1<<m)-1,memset(f,0x3f,sizeof(f));
    for(int i=0;i<m;++i) for(int j=1;j<=p;++j) if(j&(1<<i)) ++o[j];
    for(int i=1;i<=n;++i)
        for(int j=0;j<m;++j){
            t=read();
            for(int k=p;k>=1;--k) if(k&(1<<j)) g[i][k]+=t;
        }
    for(int i=0;i<=p;++i) f[1][0][i]=g[1][i],q[1][0][i]=o[i];
    for(int i=2;i<=n+1;++i)
        for(int k=0;k<=p;++k){
            for(int j=0;j<=p;++j){
                for(int w=0;w<=p;++w)  
                   if(((j|k|(k<<1)|(k>>1)|w)&p)==p&&(f[i][k][j]>f[i-1][w][k]+g[i][j]||(f[i][k][j]==f[i-1][w][k]+g[i][j]&&q[i][k][j]>q[i-1][w][k]+o[j])))
                      f[i][k][j]=f[i-1][w][k]+g[i][j],q[i][k][j]=q[i-1][w][k]+o[j];
            }
        }
    for(int i=0;i<=p;++i) if(ans1>f[n+1][i][0]||(ans1==f[n+1][i][0]&&ans2>q[n+1][i][0])) ans1=f[n+1][i][0],ans2=q[n+1][i][0];
    printf("%d %d
",ans2,ans1);            
    return 0;
}

以上是关于拯救莫莉斯题解的主要内容,如果未能解决你的问题,请参考以下文章

拯救莫莉斯

拯救莫莉斯

[GDOI2014]拯救莫莉斯

拯救莫莉斯[GDOI2014]

GDOI2014 拯救莫莉斯

GDOI2014 拯救莫莉斯