練習專題參考:傳送門
hdu 1520
題意:給出n個點,然後給出n個點對應的歡樂值,然後給出n-1條邊,a b,表示b是a的直屬上級,現在舉行乙個patry,但是要求員工和他的直屬上級不能同時來,問來的人的歡樂值的最大和是多少
思路:首先明確這是一棵有向樹,dp[i][0/1]代表第i個人來/不來的最大歡樂值。然後根據狀態轉移即可
#include using namespace std;
#define ll long long
#define pb push_back
#define mst(a, b) memset(a, b, sizeof a)
#define rep(i, x, n) for(int i = x; i <= n; ++i)
const int inf = 2e9;
const int qq = 6005;
int dp[qq][2];
vectorg[qq];
int deg[qq], rat[qq];
int n;
void dfs(int u)
dp[u][1] += rat[u];
return;
}int main()
int a, b;
while(scanf("%d%d", &a, &b) == 2)
mst(dp, 0);
for(int i = 1; i <= n; ++i)
} for(int i = 0; i < qq; ++i)
} return 0;
}
hdu 1561
最開始思路:利用拓撲來解, 但是。。。 wa
#include using namespace std;
#define ll long long
#define pb push_back
#define mk make_pair
#define mst(a, b) memset(a, b, sizeof a)
#define rep(i, x, n) for(int i = x; i <= n; ++i)
typedef pairpill;
const int qq = 200 + 10;
vectorg[qq];
int n, m, val[qq], deg[qq];
bool cmp(const pill &a, const pill &b)
int main()
int x;
rep(i, 1, n)
priority_queueq;
for(int i = 1; i <= n; ++i)
} int ans = 0;
while(!q.empty() && m--)
} printf("%d\n", ans);
} return 0;
}
可以試試這組資料
7 62 86 5
0 70 8
0 10
7 10
4 4ans:45
拓撲出來的結果是 44
正確思路:dp[i][j]代表以結點i為根的子樹上取包括結點i的j個時的最大價值,如何保證取得長度是鏈呢 ? 用dp的狀態來保證#include #include #include #include #include #include #include #include #include #include #include #include using namespace std;
#define ll long long
#define pb push_back
#define mk make_pair
#define pill pair#define mst(a, b) memset(a, b, sizeof a)
#define rep(i, x, n) for(int i = x; i <= n; ++i)
const int mod = 1e9 + 7;
const int qq = 250 + 10;
int n, m;
int dp[qq][qq], num[qq];
int mp[qq][qq], vis[qq];
void dfs(int u)
}} }
}int main()
m++;
for(int i = 0; i <= n; ++i)
} dfs(0);
printf("%d\n", dp[0][m]);
} return 0;
}
codeforces 219d
題意:n個結點,n-1條有向邊,如果邊是無向邊的話那麼從任意結點出發可以到達任意結點,現在問要選首都,要求首都能到達其他任意節點,問你最小要求改變幾條邊的方向,然後還要輸出首都的結點編號。
思路:首先以1為根結點進行dfs,求出以u為根結點到達其子樹時最小改變幾條邊的方向,然後再進行一次dfs這次維護以u個首都到達其他所有結點所需要改變邊方向數目
#include #include #include #include #include #include #include #include #include #include #include #include using namespace std;
#define ll long long
#define pb push_back
#define mk make_pair
#define pill pair#define mst(a, b) memset(a, b, sizeof a)
#define rep(i, x, n) for(int i = x; i <= n; ++i)
const int mod = 1e9 + 7;
const int qq = 2e5 + 10;
int n, s, t;
vectore[qq];
vectorf[qq];
int dp[qq], dir[qq];
void dfs(int u, int fa)
}void solve(int u, int fa)
}int main()
dfs(1, -1);
solve(1, -1);
int minx = 1e9;
for(int i = 1; i <= n; ++i)
printf("%d\n", minx);
for(int i = 1; i <= n; ++i)
} puts("");
return 0;
}
樹形dp學習
學習部落格 樹的性質 n個點,n 1條邊,任意兩個點之間只存在一條路徑,可以人為設定根節點,對於任意乙個節點只存在至多乙個父節點,其餘為子節點。記憶化樹形dp模型較為抽象難以理解,以下通過由淺到深的方式解析樹形dp以及樹的性質。樹形dp求樹的直徑 在一顆樹里找到點x,y,使得 xy 最大 如圖,我們...
樹形dp初次學習
1 什麼是樹型動態規劃 顧名思義,樹型動態規劃就是在 樹 的資料結構上的動態規劃,平時作的動態規劃都是線性的或者是建立在圖上的,線性的動態規劃有二種方向既向前和向後,相應的線性的動態規劃有二種方法既順推與逆推,而樹型動態規劃是建立在樹上的,所以也相應的有二個方向 1 葉 根 在回溯的時候從葉子節點往...
樹形DP學習總結
概述 樹形dp是dp的一種,有時候會和區間dp結合。由於樹有著天然的遞迴結構 父子結構 而且它作為一種特殊的圖 可以描述許多複雜的資訊 因此在樹就成了一種很適合dp的框架 問題 給你一棵樹 要求用最少的代價 最大的收益 完成給定的操作 樹形dp 一般來說都是從葉子從而推出根 當然 從根推葉子的情況也...