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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【HDU 4511】小明系列故事——女友的考验(AC自动机+DP)

發(fā)布時(shí)間:2025/7/14 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【HDU 4511】小明系列故事——女友的考验(AC自动机+DP) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
Problem Description 終于放寒假了,小明要和女朋友一起去看電影。這天,女朋友想給小明一個考驗(yàn),在小明正準(zhǔn)備出發(fā)的時(shí)候,女朋友告訴他,她在電影院等他,小明過來的路線必須滿足給定的規(guī)則:
  1、假設(shè)小明在的位置是1號點(diǎn),女朋友在的位置是n號點(diǎn),則他們之間有n-2個點(diǎn)可以走,小明每次走的時(shí)候只能走到比當(dāng)前所在點(diǎn)編號大的位置;
  2、小明來的時(shí)候不能按一定的順序經(jīng)過某些地方。比如,如果女朋友告訴小明不能經(jīng)過1 -> 2 -> 3,那么就要求小明來的時(shí)候走過的路徑不能包含有1 -> 2 -> 3這部分,但是1 -> 3 或者1 -> 2都是可以的,這樣的限制路徑可能有多條。
  這讓小明非常頭痛,現(xiàn)在他把問題交給了你。
  特別說明,如果1 2 3這三個點(diǎn)共線,但是小明是直接從1到3然后再從3繼續(xù),那么此種情況是不認(rèn)為小明經(jīng)過了2這個點(diǎn)的。
  現(xiàn)在,小明即想走最短的路盡快見到女朋友,又不想打破女朋友的規(guī)定,你能幫助小明解決這個問題嗎?

?

Input 輸入包含多組樣例,每組樣例首先包含兩個整數(shù)n和m,其中n代表有n個點(diǎn),小明在1號點(diǎn),女朋友在n號點(diǎn),m代表小明的女朋友有m個要求;
  接下來n行每行輸入2個整數(shù)x 和y(x和y均在int范圍),代表這n個點(diǎn)的位置(點(diǎn)的編號從1到n);
  再接著是m個要求,每個要求2行,首先一行是一個k,表示這個要求和k個點(diǎn)有關(guān),然后是順序給出的k個點(diǎn)編號,代表小明不能走k1 -> k2 -> k3 ……-> ki這個順序的路徑;
  n 和 m等于0的時(shí)候輸入結(jié)束。

  [Technical Specification]
  2 <= n <= 50
  1 <= m <= 100
  2 <= k <= 5

?

Output 對于每個樣例,如果存在滿足要求的最短路徑,請輸出這個最短路徑,結(jié)果保留兩位小數(shù);否則,請輸出”Can not be reached!” (引號不用輸出)。

?

【題目大意】n個點(diǎn),從1~n,每次只能走序號比之前序號大的,并且不能出現(xiàn)規(guī)定的順序,求1~n的最短路徑 【解題思路】 規(guī)定的順序可以看作AC自動機(jī)上的字符串,從一個節(jié)點(diǎn)到另外一個節(jié)點(diǎn) 因?yàn)槿绻厦娴穆窂經(jīng)]有辦法到達(dá)的話,就說明下面的路徑也沒有辦法到達(dá) 之后,用dp去求 dp[ i ] [ j ]? 表示現(xiàn)在位置在第 i 個節(jié)點(diǎn)同時(shí)已經(jīng)走到了AC自動機(jī)上的節(jié)點(diǎn) j ,即已經(jīng)經(jīng)過了對應(yīng)的路徑 然后枚舉狀態(tài)轉(zhuǎn)移 dp [ k ] [ t r i e [ j ] [ k ] ]? ?=? ?m i n ( d p [ k ] [ t r i e [ j ] [ k ] ] ,? ?d p [ i ] [ j ]? ?+? ?d i s ( i ,? ?k ) )? 從點(diǎn) i 走到點(diǎn) k ,AC自動機(jī)的節(jié)點(diǎn)從 j 到 k ,距離增加 dis( i ,j ) 【注意】 數(shù)組的類型定義錯誤,改了一個小時(shí)QAQ 本來應(yīng)該定義成double ,結(jié)果定義成了 i n t ,nmd #include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<queue> #include<vector> #include<cmath> using namespace std; const int MAXN = 6000; const int MAXM = 600; const double INF = 1e18; int trie[600][60],cnt; int fail[600],val[600],n,m,k; double dp[60][600]; struct node {double x, y; }a[60]; void insert(double *v) {int now = 0;for (int i = 1; i <=k; i++){int u = v[i];if (!trie[now][u]){trie[now][u] = ++cnt;}now = trie[now][u];}val[now]=1; } void get_fail() {int now = 0;queue<int> q;for (int i = 1; i <=n; i++)if (trie[now][i]){fail[trie[now][i]] = 0;q.push(trie[now][i]);}while (!q.empty()){int u = q.front(); q.pop();if (val[fail[u]])val[u]=1;for (int i = 1; i <=n; i++){int v = trie[u][i];if (v){fail[v] = trie[fail[u]][i];q.push(v);}else{trie[u][i] = trie[fail[u]][i];}}}return; } double dis(int i, int j) {double tmp = (a[i].x - a[j].x)*(a[i].x - a[j].x) + (a[i].y - a[j].y)*(a[i].y - a[j].y);return sqrt(tmp); } double v[600]; double solve() {double minn = INF;for (int i = 1; i <= n; i++)for (int j = 0; j <= cnt; j++)dp[i][j] = INF;dp[1][trie[0][1]] = 0;for (int i = 1; i <= n; i++){for (int j = 0; j <= cnt; j++){if (dp[i][j]<INF){for (int k = i + 1; k <= n; k++)if (!val[trie[j][k]])dp[k][trie[j][k]] = min(dp[k][trie[j][k]], dp[i][j] + dis(i, k));}}}for(int i=0;i<=cnt;i++)minn = min(minn, dp[n][i]);return minn; } int main() {while (scanf("%d%d", &n, &m) && n && m){cnt = 0;memset(trie, 0, sizeof(trie));memset(val, 0, sizeof(val));memset(fail, 0, sizeof(fail));for (int i = 1; i <= n; i++)scanf("%lf%lf", &a[i].x, &a[i].y);while(m--){scanf("%d", &k);for (int i = 1; i <= k; i++)scanf("%lf", &v[i]);insert(v);}get_fail();double ans = solve();if (ans >= INF)printf("Can not be reached!\n");elseprintf("%.2f\n", ans);}return 0; } View Code

?

轉(zhuǎn)載于:https://www.cnblogs.com/rentu/p/11336071.html

總結(jié)

以上是生活随笔為你收集整理的【HDU 4511】小明系列故事——女友的考验(AC自动机+DP)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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