JS案例:質數判斷、質因數分解、兩個正整數的最大公因數和最小公倍數
阿新 • • 發佈:2020-12-04
寫的過程十分煎熬,實在是不會寫,還要繼續熟悉啥是揹包。。。。
動態規劃最難的不是轉移方程,而是設計dp的含義啊
#include<iostream> #include<cstring> #include<vector> #include<algorithm> #include<cstdio> using namespace std; const int maxn = 200 + 11; typedef long long ll; ll f[110][110][110], g[110][110][110]; int k, n, m; ll sum[110], dis[maxn]; struct Node { int p; int len; Node(int a, int b) :p(a), len(b) {} }; vector<Node>G[maxn]; void add(int be, int en, int len) { G[be].push_back(Node(en, len)); } int s[maxn]; int cnt = 0; int dfs(int x, int fa, ll d) { s[cnt++] = x; dis[x] = d; for (int i = 0; i < G[x].size(); i++) { int p = G[x][i].p; ll ln = G[x][i].len; if (p == fa) continue; dfs(p, x, d + ln); for (int b = 0; b < cnt; b++) { int ff = s[b]; for (int j = k; j >= 0; j--) { f[x][ff][j] += f[p][ff][0]; g[x][ff][j] += f[p][x][0]; for (int a = 0; a <= j; a++) {//01揹包 f[x][ff][j] = min(f[x][ff][j], f[x][ff][j - a] + f[p][ff][a]); g[x][ff][j] = min(g[x][ff][j], g[x][ff][j - a] + f[p][x][a]); } } } } //補齊x--->ff的流量 for (int i = 0; i < cnt; i++) { int ff = s[i]; for (int j = 0; j <= k; j++) { if (j == 0) { f[x][ff][j] += sum[x] * (dis[x] - dis[ff]); } else { //判斷是否讓x成為工廠 f[x][ff][j] = min(f[x][ff][j] + sum[x] * (dis[x] - dis[ff]), g[x][ff][j - 1]); } } } cnt--; return 0; } int main() { scanf("%d %d", &n, &k); for (int i = 1; i <= n; i++) { int be = i, en, len; scanf("%lld %d %d", &sum[i], &en, &len); add(be, en, len); add(en, be, len); } cnt = 0; dfs(0, -1, 0); printf("%lld\n", f[0][0][k]); return 0; }