1118. 分成互质组
给定 n 个正整数,将它们分组,使得每组中任意两个数互质。
至少要分成多少个组?
输入格式
第一行是一个正整数 n。
第二行是 n 个不大于10000的正整数。
输出格式
一个正整数,即最少需要的组数。
数据范围
1≤n≤10
输入样例:
6
14 20 33 117 143 175
输出样例:
3
#include <bits/stdc++.h>
using namespace std;
const int N = 10;
int n, a[N], ans = N, len;
vector<int>g[N];
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
bool check(int u, int c)
{
for (int i = 0; i < g[c].size(); i++)
if (gcd(g[c][i], u) > 1)return false;
return true;
}
void dfs(int u)
{
if (u == n)
{
ans = min(ans, len);
return;
}
for (int i = 0; i < len; i++)
{
if (check(a[u], i))
{
g[i].push_back(a[u]);
dfs(u + 1);
g[i].pop_back();
}
}
g[len++].push_back(a[u]);
dfs(u + 1);
g[--len].pop_back();
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)cin >> a[i];
dfs(0);
cout << ans << endl;
return 0;
}
165. 小猫爬山
翰翰和达达饲养了 N 只小猫,这天,小猫们要去爬山。
经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了(呜咕>_<)。
翰翰和达达只好花钱让它们坐索道下山。
索道上的缆车最大承重量为 W,而 N 只小猫的重量分别是 C1、C2……CN。
当然,每辆缆车上的小猫的重量之和不能超过 W。
每租用一辆缆车,翰翰和达达就要付 1 美元,所以他们想知道,最少需要付多少美元才能把这 N 只小猫都运送下山?
输入格式
第 1 行:包含两个用空格隔开的整数,N 和 W。
第 2…N+1 行:每行一个整数,其中第 i+1 行的整数表示第 i 只小猫的重量 Ci。
输出格式
输出一个整数,表示最少需要多少美元,也就是最少需要多少辆缆车。
数据范围
1≤N≤18,
1≤Ci≤W≤108
输入样例:
5 1996
1
2
1994
12
29
输出样例:
2
#include <bits/stdc++.h>
using namespace std;
const int N = 20;
int n, m;
int w[N];
int sum[N];
int ans = N;
void dfs(int u, int k)
{
if (k >= ans)return;
if (u == n)
{
ans = k;
return;
}
for (int i = 0; i < k; i++)
{
if (sum[i] + w[u] <= m)
{
sum[i] += w[u];
dfs(u + 1, k);
sum[i] -= w[u];
}
}
sum[k] = w[u];
dfs(u + 1, k + 1);
sum[k] = 0;
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i++)cin >> w[i];
sort(w, w + n);
reverse(w, w + n);
dfs(0, 0);
cout << ans << endl;
return 0;
}
1127. 香甜的黄油
农夫John发现了做出全威斯康辛州最甜的黄油的方法:糖。
把糖放在一片牧场上,他知道 N 只奶牛会过来舔它,这样就能做出能卖好价钱的超甜黄油。
当然,他将付出额外的费用在奶牛上。
农夫John很狡猾,就像以前的巴甫洛夫,他知道他可以训练这些奶牛,让它们在听到铃声时去一个特定的牧场。
他打算将糖放在那里然后下午发出铃声,以至他可以在晚上挤奶。
农夫John知道每只奶牛都在各自喜欢的牧场(一个牧场不一定只有一头牛)。
给出各头牛在的牧场和牧场间的路线,找出使所有牛到达的路程和最短的牧场(他将把糖放在那)。
数据保证至少存在一个牧场和所有牛所在的牧场连通。
输入格式
第一行: 三个数:奶牛数 N,牧场数 P,牧场间道路数 C。
第二行到第 N+1 行: 1 到 N 头奶牛所在的牧场号。
第 N+2 行到第 N+C+1 行:每行有三个数:相连的牧场A、B,两牧场间距 D,当然,连接是双向的。
输出格式
共一行,输出奶牛必须行走的最小的距离和。
数据范围
1≤N≤500,
2≤P≤800,
1≤C≤1450,
1≤D≤255
输入样例:
3 4 5
2
3
4
1 2 1
1 3 5
2 3 7
2 4 3
3 4 5
输出样例:
8
#include <bits/stdc++.h>
using namespace std;
const int N = 810, M = 3000;
int n, p, m;
int id[N];
int h[N], e[M], ne[M], w[M], idx;
int dist[N], q[N];
bool st[N];
void add(int a, int b, int c)
{
e[idx] = b;
w[idx] = c;
ne[idx] = h[a];
h[a] = idx++;
}
int spfa(int start)
{
memset(dist, 0x3f, sizeof dist);
dist[start] = 0;
queue<int>q;
q.push(start);
while (q.size())
{
auto t = q.front();
q.pop();
st[t] = false;
for (int i = h[t]; ~i; i = ne[i])
{
int j = e[i];
if (dist[j] > dist[t] + w[i])
{
dist[j] = dist[t] + w[i];
if (!st[j])
{
st[j] = true;
q.push(j);
}
}
}
}
int res = 0;
for (int i = 0; i < n; i++)
{
int j = id[i];
if (dist[j] == 0x3f3f3f3f)return 0x3f3f3f3f;
res += dist[j];
}
return res;
}
int main()
{
cin >> n >> p >> m;
for (int i = 0; i < n; i++)cin >> id[i];
memset(h, -1, sizeof h);
for (int i = 0; i < m; i++)
{
int a, b, c;
cin >> a >> b >> c;
add(a, b, c);
add(b, a, c);
}
int res = 0x3f3f3f3f;
for (int i = 1; i <= p; i++)res = min(res, spfa(i));
cout << res << endl;
return 0;
}
1126. 最小花费
在 n 个人中,某些人的银行账号之间可以互相转账。
这些人之间转账的手续费各不相同。
给定这些人之间转账时需要从转账金额里扣除百分之几的手续费,请问 A 最少需要多少钱使得转账后 B 收到 100 元。
输入格式
第一行输入两个正整数 n,m,分别表示总人数和可以互相转账的人的对数。
以下 m 行每行输入三个正整数 x,y,z,表示标号为 x 的人和标号为 y 的人之间互相转账需要扣除 z% 的手续费 ( z<100 )。
最后一行输入两个正整数 A,B。
数据保证 A 与 B 之间可以直接或间接地转账。
输出格式
输出 A 使得 B 到账 100 元最少需要的总费用。
精确到小数点后 8 位。
数据范围
1≤n≤2000,
m≤105
输入样例:
3 3
1 2 1
2 3 2
1 3 3
1 3
输出样例:
103.07153164
#include <bits/stdc++.h>
using namespace std;
const int N = 2010;
double dist[N];
bool st[N];
double g[N][N];
int n, m, s, t;
void dijkstra()
{
dist[s] = 1;
for (int i = 0; i < n; i++)
{
int t = -1;
for (int j = 1; j <= n; j++)
{
if (!st[j] && (dist[t] < dist[j]))
t = j;
}
st[t] = true;
for (int j = 1; j <= n; j++)
dist[j] = max(dist[j], dist[t] * g[t][j]);
}
}
int main()
{
cin >> n >> m;
while (m--)
{
int a, b, c;
cin >> a >> b >> c;
double z = (100.0 - c) / 100;
g[a][b] = g[b][a] = max(g[a][b], z);
}
cin >> s >> t;
dijkstra();
printf("%.8f\n", 100 / dist[t]);
return 0;
}