日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

P1433 吃奶酪(状压dp)

發(fā)布時間:2024/9/3 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P1433 吃奶酪(状压dp) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

洛谷 / 題目列表 / 題目詳情
P1433 吃奶酪
提交
23.28k
通過
9.30k
時間限制
1.00s
內(nèi)存限制
125.00MB
題目描述
房間里放著n塊奶酪。一只小老鼠要把它們都吃掉,問至少要跑多少距離?老鼠一開始在(0,0)點處。

輸入格式
第一行一個數(shù)n (n<=15)

接下來每行2個實數(shù),表示第i塊奶酪的坐標。

兩點之間的距離公式=sqrt((x1-x2)(x1-x2)+(y1-y2)(y1-y2))

輸出格式
一個數(shù),表示要跑的最少距離,保留2位小數(shù)。

輸入輸出樣例
輸入 #1 復制

4 1 1 1 -1 -1 1 -1 -1

輸出 #1 復制

7.41

···
/*
預處理一下各個點之間的距離,
暴搜可以過。
但是!!
這是經(jīng)典的NP問題,
數(shù)據(jù)比較小,用狀壓dp,d它!!!!

*/
第一種寫法:
虛擬一個終點(原來的終點到它的距離為0,
記的起點(0,0)到其他點的距離要算上),
就相當于前幾天寫的:最短Hamilton路徑(狀壓dp)

#include <bits/stdc++.h> using namespace std; const int N = 1<<20; double dp[N][20]; struct Point {double x,y; } p[20]; double getDis(int i,int j) {return sqrt(pow(p[i].x-p[j].x,2)+pow(p[i].y-p[j].y,2)); } double dis[20][20]; int n; void init() {for(int i = 0; i <= n; i++){for(int j = i; j <= n; j++){dis[i][j] = dis[j][i] = getDis(i,j);}}int t = n+2;for(int i = 0; i < (1<<t); i++){for(int j = 0; j < t; j++){dp[i][j] = 1e16;}}dp[1][0] = 0; } int main() {cin>>n;p[0].x = p[0].y = 0;for(int i = 1; i <= n; i++){cin>>p[i].x>>p[i].y;}init();n = n+2;//原來起點(0,0),還有虛擬了一個(原來所有終點的)終點for(int i = 1; i < (1<<n); i++){for(int j = 0; j < n; j++){if((i>>j)&1)for(int k = 0; k < n; k++){dp[i][j] = min(dp[i][j],dp[i-(1<<j)][k]+dis[k][j]);}}}cout.precision(2);cout<<fixed<<dp[(1<<n)-1][n-1]<<endl;return 0; }

為了更深入了解狀壓dp,
第二種寫法,不虛擬終點,
最終對所有終點的求個最小值
(時間,空間復雜度都更優(yōu))

#include <bits/stdc++.h> using namespace std; const int N = 1<<17; double dp[N][17]; struct Point {double x,y; } p[17]; double getDis(int i,int j) {return sqrt(pow(p[i].x-p[j].x,2)+pow(p[i].y-p[j].y,2)); } double dis[17][17]; int n; void init() {for(int i = 0; i <= n; i++){for(int j = i; j <= n; j++){dis[i][j] = dis[j][i] = getDis(i,j);}}int t = n+1;for(int i = 0; i < (1<<t); i++){for(int j = 0; j < t; j++){dp[i][j] = 1e16;}}dp[1][0] = 0; } int main() {cin>>n;if(!n){cout<<"0.00"<<endl;return 0;}p[0].x = p[0].y = 0;for(int i = 1; i <= n; i++){cin>>p[i].x>>p[i].y;}init();n = n+1;for(int i = 1; i < (1<<n); i++){for(int j = 1; j < n; j++){if((i>>j)&1)for(int k = 0; k < n; k++){dp[i][j] = min(dp[i][j],dp[i-(1<<j)][k]+dis[k][j]);}}}double ans = 1e16;for(int i = 1; i < n; i++)ans = min(ans,dp[(1<<n)-1][i]);cout.precision(2);cout<<fixed<<ans<<endl;return 0; }

總結(jié)

以上是生活随笔為你收集整理的P1433 吃奶酪(状压dp)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。