1. 程式人生 > 實用技巧 >JS案例:質數判斷、質因數分解、兩個正整數的最大公因數和最小公倍數

JS案例:質數判斷、質因數分解、兩個正整數的最大公因數和最小公倍數

寫的過程十分煎熬,實在是不會寫,還要繼續熟悉啥是揹包。。。。
動態規劃最難的不是轉移方程,而是設計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;
}