天梯賽的一點小準備

由於天梯賽不能帶模板,對於我這種模板嚴重依賴患者是很難受的,又因爲去年打那麼菜,今年題目不是太難的話怎麼着也得上200呀,所以來重新打一遍模板,交一下裸題驗證其正確性。

需要準備的也不是太多,主要是一些基本的圖論算法以及dp。畢竟都是理解了的,應該不會耗時很久。

就按照白書上面的順序來敲吧。

 

一、01揹包

題目:Bone Collector

二維的:

int dp[maxn][maxn];
int w[maxn], v[maxn];

int main()
{
	int t; scanf("%d", &t);
	while(t--){
		memset(dp, 0, sizeof(dp));
		int n, V; scanf("%d %d", &n, &V);
		rep(i, 1, n) scanf("%d", v + i);
		rep(i, 1, n) scanf("%d", w + i);
		rep(i, 1, n){
			rep(j, 0, V){
				if(w[i] > j) dp[i][j] = dp[i-1][j];
				else dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i]);
			}
		}
		printf("%d\n", dp[n][V]);
	}
	return 0;
}

一維的:

int dp[maxn];
int w[maxn], v[maxn];

int main()
{
	int t; scanf("%d", &t);
	while(t--){
		memset(dp, 0, sizeof(dp));
		int n, V; scanf("%d %d", &n, &V);
		rep(i, 1, n) scanf("%d", v + i);
		rep(i, 1, n) scanf("%d", w + i);
		rep(i, 1, n){
			Rep(j, V, w[i]){
				dp[j] = max(dp[j], dp[j-w[i]] + v[i]);
			}
		}
		printf("%d\n", dp[V]);
	}
	return 0;
}

 

二、LCS問題

題目:Common Subsequence

char s[maxn], t[maxn];
int dp[maxn][maxn];

int main()
{
	while(~scanf(" %s %s", s + 1, t + 1)){
		memset(dp, 0, sizeof(dp));
		int n = strlen(s + 1), m = strlen(t + 1);
		rep(i, 1, n){
			rep(j, 1, m){
				if(s[i] == t[j]) dp[i][j] = dp[i-1][j-1] + 1;
				else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
			}
		}
		printf("%d\n", dp[n][m]);
	}
	return 0;
}

 

三、完全揹包問題

題目:Piggy-Bank

直接一維吧:

int w[505], v[505];
int dp[10005];

int main()
{
	int t; scanf("%d", &t);
	while(t--){
		int e, f; scanf("%d %d", &e, &f);
		int V = f - e;
		rep(i, 0, V) dp[i] = inf;
		int n; scanf("%d", &n);
		rep(i, 1, n) scanf("%d %d", v + i, w + i);
		dp[0] = 0;
		rep(i, 1, n){
			rep(j, w[i], V){
				dp[j] = min(dp[j], dp[j-w[i]] + v[i]);
			}
		}
		if(dp[V] == inf) puts("This is impossible.");
		else printf("The minimum amount of money in the piggy-bank is %d.\n", dp[V]);
	}
	return 0;
}

四、多重部分和問題

題目:Dividing

int a[10] = {0, 1, 2, 3, 4, 5, 6 }, m[10];
int dp[maxn];

int main()
{
	int cnt = 0;
	while(~scanf("%d", m + 1)){
		rep(i, 2, 6) scanf("%d", m + i);
		bool f = 0;
		rep(i, 1, 6) if(m[i]) f = 1;
		if(!f) break;
		printf("Collection #%d:\n", ++cnt);
		int sum = 0;
		rep(i, 1, 6){
			sum += i * m[i];
		}
		if(sum & 1) { puts("Can't be divided.\n"); continue; }
		sum /= 2;
		fill(dp, dp + sum + 1, -1);
		dp[0] = 0;
		rep(i, 1, 6){
			rep(j, 0, sum){
				if(dp[j] >= 0) dp[j] = m[i];
				else if(j < a[i] || dp[j-a[i]] <= 0){
					dp[j] = -1;
				}
				else dp[j] = dp[j-a[i]] - 1;
			}
		}
		if(dp[sum] >= 0) puts("Can be divided.");
		else puts("Can't be divided.");
		puts("");
	}
	return 0;
}

五、LIS問題

題目:Longest Ordered Subsequence

int a[maxn];
int dp[maxn];

int main()
{
	int n; scanf("%d", &n);
	rep(i, 1, n) scanf("%d", a + i);
	fill(dp, dp + n + 1, inf);
	rep(i, 1, n){
		*lower_bound(dp + 1, dp + n + 1, a[i]) = a[i];
	}
	printf("%d\n", lower_bound(dp + 1, dp + n + 1, inf) - dp - 1);
	return 0;
}

六、優先隊列的定義&重載

struct node{
	int x, y, t;
	friend bool operator < (node a, node b){
		return a.t > b.t;
	}
};

priority_queue<node> q;

七、並查集

題目:The Suspects

int fa[maxn];
int n, m;

int Find(int x){
	return x == fa[x] ? x : fa[x] = Find(fa[x]);
}

void uni(int x, int y){
	fa[Find(x)] = Find(y);
}

void init(){
	rep(i, 0, n) fa[i] = i;
}

int main()
{
	while(~scanf("%d %d", &n, &m) && !(!n && !m)){
		init();
		rep(i, 1, m){
			int num; scanf("%d", &num);
			int x; scanf("%d", &x);
			rep(j, 1, num - 1){
				int y; scanf("%d", &y);
				uni(x, y);
			}
		}
		int fa0 = Find(0);
		int cnt = 1;
		rep(i, 1, n - 1){
			if(Find(i) == fa0) cnt++;
		}
		printf("%d\n", cnt);
	}
	return 0;
}

 

八、最短路問題

floyd:

問題:Cow Contest (求有向圖傳遞閉包)

bool vis[maxn][maxn];

int main()
{
	int n, m; scanf("%d %d", &n, &m);
	rep(i, 1, n) vis[i][i] = 1;
	rep(i, 1, m){
		int u, v; scanf("%d %d", &u, &v);
		vis[u][v] = 1;
	}
	rep(k, 1, n){
		rep(i, 1, n){
			rep(j, 1, n){
				vis[i][j] |= (vis[i][k] && vis[k][j]);
			}
		}
	}
	int cnt = 0;
	rep(i, 1, n){
		bool f = 1;
		rep(j, 1, n){
			if(!vis[i][j] && !vis[j][i]) f = 0;
		}
		if(f) cnt++;
	}
	printf("%d\n", cnt);
	return 0;
}

Bellman_Ford:

題目:Wormholes

struct edge{
	int from, to, cost;
}e[maxn];

int d[maxn];
int n, m, m2;

bool Bellman_Frod(int s){
	memset(d, 0, sizeof(d));
	rep(i, 1, n){
		rep(j, 1, 2 * m + m2){
			edge t = e[j];
			if(d[t.to] > d[t.from] + t.cost){
				d[t.to] = d[t.from] + t.cost;
				if(i == n) return true;
			}
		}
	}
	return false;
}

int main()
{
	int t; scanf("%d", &t);
	while(t--){
		scanf("%d %d %d", &n, &m, &m2);
		rep(i, 1, m){
			scanf("%d %d %d", &e[i].from, &e[i].to, &e[i].cost);
			e[i+m].from = e[i].to, e[i+m].to = e[i].from, e[i+m].cost = e[i].cost;
		}
		rep(i, 2 * m + 1, 2 * m + m2){
			scanf("%d %d %d", &e[i].from, &e[i].to, &e[i].cost);
			e[i].cost = -e[i].cost;
		}
		puts(Bellman_Frod(1) ? "YES" : "NO");
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章