• LG 3959 宝藏


    状压DP

    蒟蒻想了个(O(N^3ast 3^N))

    膜拜SZR博客之后
    才知道怎么优化掉一个N
    码力同翔
    1.5h才过样例

    SZR's blog

    #include <iostream>
    #include <cassert>
    
    using namespace std;
    
    const long long LONF=4567891012345678910LL;
    const int INF=1034567890;
    const int MAXN=13;
    const int MAXM=4111;
    
    int N, M;
    long long Map[MAXN][MAXN];
    long long F[MAXN][MAXN][MAXM];
    int Cnt[MAXM];
    int Mat[MAXN][MAXN][MAXM];
    long long MinC, Cost;
    
    long long lmin(long long a, long long b){
    	return (a>b)?b:a;
    }
    
    int main(){
    	ios_base::sync_with_stdio(false);
    	
    	cin >> N >> M;
    	for(int i=0;i<N;++i)
    		for(int j=0;j<N;++j)
    			Map[i][j]=(long long)(INF);
    	for(int i=0;i<N;++i)	Map[i][i]=0LL;
    	for(int i=1, a, b, v;i<=M;++i){
    		cin >> a >> b >> v;--a;--b;
    		Map[a][b]=lmin(Map[a][b], (long long)(v));
    		Map[b][a]=lmin(Map[b][a], (long long)(v));
    	}
    	
    	M=(1<<N);
    	
    	for(int i=0;i<=N;++i)
    		for(int j=0;j<=N;++j)
    			for(int p=0;p<M;++p)
    				F[i][j][p]=LONF, Mat[i][j][p]=-1;
    	
    	for(int i=0, k;i<M;++i){
    		k=i;Cnt[i]=0;
    		while(k>0){
    			if(k&1)	++Cnt[i];
    			k>>=1;
    		}
    	}
    	
    	for(int s=1, i=0;s<M;s<<=1, ++i){
    		for(int j=0;j<N;++j){
    			F[i][j][s]=0LL;
    		}
    		for(int j=0;j<N;++j){
    			if(j==i)	continue;
    			for(int d=0;d<N;++d){
    				Mat[j][d][s]=i;
    			}
    		}
    	}
    	
    	for(int s=1;s<M;++s){
    		if(Cnt[s]<=1)	continue;
    		for(int ss=(s-1)&s, iss;ss>0;ss=(ss-1)&s){
    			iss=s-ss;
    			for(int d=0;d+Cnt[s]<=N;++d){
    				for(int i=0, j;i<N;++i){
    					if(((1<<i)&ss)==0)	continue;
    					j=Mat[i][d][iss];
    					//cout << i << " " << d << " " << iss << endl;
    					assert(j>-1 && j<N);
    					//cout << "(" << i << "," << d << "," << s << ")<-(" << j << "," << d+1 << "," << iss << ")" << endl;
    					F[i][d][s]=lmin(F[i][d][s], F[i][d][ss]+Map[i][j]*(long long)(d+1)+F[j][d+1][iss]);
    				}
    			}
    		}
    		for(int i=0;i<N;++i){
    			if(((1<<i)&s)!=0)	continue;
    			for(int d=0;d+Cnt[s]<=N;++d){
    				Mat[i][d][s]=-1;MinC=LONF;
    				for(int j=0;j<N;++j){
    					if(((1<<j)&s)==0)	continue;
    					Cost=F[j][d+1][s]+Map[i][j]*(long long)(d+1);
    					if(Cost<MinC){
    						MinC=Cost;Mat[i][d][s]=j;
    					}
    				}
    			}
    		}
    	}
    	
    	/*
    	for(int s=1;s<M;++s){
    		for(int i=0;i<N;++i){
    			if(((1<<i)&s)==0)	continue;
    			for(int d=0;d+Cnt[s]<=N;++d){
    				cout << i << " " << d << " " << s << " " << F[i][d][s] << endl;
    			}
    		}
    	}
    	*/
    	
    	long long ANS=LONF;
    	for(int i=0;i<N;++i)
    		ANS=lmin(ANS, F[i][0][M-1]);
    	cout << ANS << endl;
    	
    	return 0;
    }
    
    
  • 相关阅读:
    45个非常有用的Oracle查询语句(转自开源中国社区)
    Oracle创建表空间及用户
    table里面,怎么根据checkbox选择的一行中的某个单元格的值是否为空,来判断是否该选中
    点击上传按钮,文件自动上传
    如何给frame标签的src属性以及a标签的href属性自动设值
    Tomcat内存溢出的三种情况及解决办法分析
    Java中判断字符串是否为数字的五种方法
    SSH项目里面 忘记密码的邮件发送功能
    form表单提交时,action怎么带参数
    因为多余jar包,所报的错
  • 原文地址:https://www.cnblogs.com/Pickupwin/p/8688766.html
Copyright © 2020-2023  润新知