码迷,mamicode.com
首页 > 其他好文 > 详细

拯救莫莉斯题解

时间:2019-10-14 23:53:10      阅读:83      评论:0      收藏:0      [点我收藏+]

标签:include   turn   sqrt   for   get   code   ||   getc   const   

拯救莫莉斯题解

实际上是水题啦,
观察数据发现,\(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\n",ans2,ans1);            
    return 0;
}

拯救莫莉斯题解

标签:include   turn   sqrt   for   get   code   ||   getc   const   

原文地址:https://www.cnblogs.com/ljk123-de-bo-ke/p/11674692.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!