ZJU 1346 Comparing Your Heroes 狀態壓縮DP 拓撲排序的計數

來源:互聯網
上載者:User

標籤:style   blog   http   color   os   io   資料   for   

做多校的時候遇見一個求拓撲排序數量的題,就順便來寫了一下。

題意:

  你有個朋友是KOF的狂熱粉絲,他有一個對其中英雄的強弱比較,讓你根據這些比較關係來給這些英雄排名。問一共有多少種排名方式。

思路:

  用dp[S]記錄目前狀態的數量。 S表示拓撲排序中當前階段已經被排序的點的集合。然後就可以枚舉當前排序的點,轉移的條件是這個點的所有前驅都被排序,而且這個點沒被排序。然後轉移就好了,最終狀態就是所有點都完成排序。

代碼:

 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <algorithm> 7 #include <string> 8 #include <queue> 9 #include <stack>10 #include <vector>11 #include <map>12 #include <set>13 #include <functional>14 #include <time.h>15 16 using namespace std;17 18 const int INF = 1<<30;19 const int MAXN = 16;20 21 int dp[1<<MAXN];22 int pre[MAXN]; //記錄每個點的前驅集合23 char name[MAXN][MAXN]; //記錄每個人物的名字24 char str[2][MAXN];25 int n, m;26 27 void input() {28     //讀資料及其之間的關係。29     //並且把他們存起來,給每一個名字一個編號30     //處理出來每個點的前驅存在pre[]中31     int u, v;32     n = 0;33     memset(pre, 0, sizeof(pre));34     for (int i = 0; i < m; i++) {35         scanf("%s%s", str[0], str[1]);36 37         for (u = 0; u < n; u++) //找到這個字串38             if (strcmp(name[u], str[0])==0)39                 break;40         if (u==n) strcpy(name[n++], str[0]); //如果沒找到,插入這個字串41 42         for (v = 0; v < n; v++)43             if (strcmp(name[v], str[1])==0)44                 break;45         if (v==n) strcpy(name[n++], str[1]);46 47         pre[v] |= (1<<u); //u是v的前驅,所以,把u加進v的前驅集合48     }49 //for (int i = 0; i < n; i++) printf("%d ", pre[i]); puts(""); //輸出前驅集合50 }51 52 void solve() {53     //動態規劃54     //枚舉每個狀態(已經有拓撲序的集合),然後枚舉假如這個集合的點55     memset(dp, 0, sizeof(dp));56     dp[0] = 1; //初始狀態57 58     for (int S = 0; S < (1<<n); S++) if (dp[S]!=0) { //剪枝59         for (int i = 0; i < n; i++) if (((S&pre[i])==pre[i]) && !(S&(1<<i))) { //i的前驅全部在此狀態中,並且i不在60             dp[S|(1<<i)] += dp[S];61         }62     }63 64     printf("%d\n", dp[(1<<n)-1]); //最終狀態時所有點都被排序65 }66 67 int main() {68     #ifdef Phantom0169         freopen("ZJU1346.txt", "r", stdin);70     #endif //Phantom0171 72     while (scanf("%d", &m)!=EOF) {73         input();74         solve();75     }76 77     return 0;78 }
ZJU 1346

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.