zoukankan      html  css  js  c++  java
  • 洛谷P1171 售货员的难题 dp

    题目链接:https://www.luogu.com.cn/problem/P1171

    货郎担问题,经典的NPC难题,本题规模小,可用动态规划求解
    (dp[i][S]) 表示当前在城市 i,访问集合 S 中的城市各一次后回到城市 0 的最短长度,则

    [dp[i][S] = min{dp[j][S-{j}] + dis[j][i]},其中 j eq 0 ]

    注意两村庄之间的道路不一样长!!
    边界条件为(dp[i][0] = dis[0][i])
    答案即为 (dp[0][{1,2,3,...,n-1}])

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #include<stack>
    #include<queue>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 20;
    
    int n;
    int dis[maxn][maxn],dp[maxn][1<<maxn];
    
    ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }
    
    int main(){
    	memset(dp,0x3f,sizeof(dp)); 
    	n = read();
    	for(int i=0;i<n;i++){
    		for(int j=0;j<n;j++){
    			dis[i][j] = read();
    		}
    	}
    	
    //	for(int i=0;i<n;i++){
    //		for(int j=0;j<n;j++){
    //			printf("%d ",dis[i][j]);
    //		}printf("
    ");
    //	}
    	
    	for(int i=0;i<n;i++) dp[i][0] = dis[0][i];
    	
    	for(int s=1;s<(1<<(n));++s){
    		if(s&1) continue;
    		for(int i=0;i<n;++i){	
    			if(!(s & (1<<i))){
    				for(int j=1;j<n;++j){
    					if(s & (1<<j)){
    						dp[i][s] = min(dp[i][s],dp[j][s^(1<<j)] + dis[j][i]);
    					}
    				}
    //				printf("%d %d dp:%d
    ",i,ss,dp[i][ss]);
    			}
    		}
    	}
    	
    	int ans = 0;
    	
    	printf("%d
    ",dp[0][((1<<n)-1)^1]);
    	
    	return 0;
    }
  • 相关阅读:
    python基础(5)
    python基础(4)
    python基础(3)
    python基础(2)
    第一个python程序(2)
    第一个python教程(1)
    【jQuery】
    【JavaScript】
    【练习】HTML+CSS
    【练习】Html
  • 原文地址:https://www.cnblogs.com/tuchen/p/13829388.html
Copyright © 2011-2022 走看看