• 【洛谷P3959】宝藏


    题目大意:比较复杂,点 这里 看题。

    题解:对于状态压缩 dp 来讲,阶段的确立十分重要。本题中,采用以层次为阶段进行状压 dp。
    设状态 (f[i][S]) 表示开凿到深度 (i),当前已经打通的点集为 (S) 时的最小花费。
    则状态转移方程为 $$f[i][S]=min{f[i-1][S']+(i-1)*cost(S',S) }$$
    因此,预处理出状态转移之间的花费和对于每个状态而言,可行的状态即可。
    时间复杂度为 (O(n*3^n))

    代码如下

    #include <bits/stdc++.h>
    #define pb push_back
    using namespace std;
    const int maxn=15;
    const int maxs=1<<12;
    const int inf=0x3f3f3f3f;
    
    int n,m,ans,G[maxn][maxn];
    int road[maxs][maxn],expand[maxs],f[maxn][maxs];
    vector<int> valid[maxs],cost[maxs];
    
    void prework(){
    	memset(road,0x3f,sizeof(road));
    	for(int s=0;s<1<<n;s++){
    		expand[s]=s;
    		for(int i=1;i<=n;i++){
    			if(s>>(i-1)&1){
    				road[s][i]=0;
    				for(int j=1;j<=n;j++){
    					if(G[i][j]==inf)continue;
    					expand[s]|=1<<(j-1);
    					road[s][j]=min(road[s][j],G[i][j]);
    				}
    			}
    		}
    	}
    	for(int s=0;s<1<<n;s++){
    		for(int k=(s-1)&s;k;k=(k-1)&s){
    			if((s&expand[k])==s){
    				int sum=0;
    				for(int i=1;i<=n;i++)
    					if((s^k)>>(i-1)&1)sum+=road[k][i];
    				valid[s].pb(k),cost[s].pb(sum);
    			}
    		}
    	}
    }
    
    void solve(){
    	memset(f,0x3f,sizeof(f));
    	for(int i=1;i<=n;i++)f[1][1<<(i-1)]=0;
    	ans=f[1][(1<<n)-1];
    	for(int i=2;i<=n;i++){
    		for(int s=0;s<1<<n;s++){
    			for(int p=0;p<valid[s].size();p++){
    				int k=valid[s][p];
    				f[i][s]=min(f[i][s],f[i-1][k]+(i-1)*cost[s][p]);
    			}
    		}
    		ans=min(ans,f[i][(1<<n)-1]);
    	}
    	printf("%d
    ",ans);
    }
    
    int main(){
    	scanf("%d%d",&n,&m);
    	memset(G,0x3f,sizeof(G));
    	for(int i=1;i<=m;i++){
    		int x,y,z;scanf("%d%d%d",&x,&y,&z);
    		G[x][y]=G[y][x]=min(G[x][y],z);
    	}	
    	prework();
    	solve();
    	return 0;
    } 
    
  • 相关阅读:
    Java算法之 二分搜寻法 ( 搜寻原则的代表)
    Java算法之 二分搜寻法 ( 搜寻原则的代表)
    基本选择器示例 改变颜色
    jquery 2.3.1 基本选择器
    ModelMapper:从对象到对象的映射库
    老司机带你在MySQL领域“大吉大利,晚上吃鸡”
    jquery getElementById
    jquery getElementsByName
    根据id获取元素
    win10能点开开始菜单但是不能点里面的功能
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10803775.html
Copyright © 2020-2023  润新知