T1:
题目大意:
有n个盒子,第i个盒子里的糖果数量为[Li,Ri],且所有盒子的糖果数量总和为C。现在要选出最少的盒子,使得这些盒子里的糖果数量总和不会小于X。
基本思路:
假设我们选择了盒子集合S。则里面糖果数量至少为 T=max(sigma(i 属于S)Li, C-sigma(i不属于S)Ri)。我们的目标是T>= X且|S|最小。所以可以把sigma(I 属于S)Li,以及C-sigma(i不属于S)Ri单独考虑。这只要排个序就可以了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<cstdlib>
#include<ctime>
using namespace std;
int cmp(const int &a,const int &b){
return a>b;
}
class MysticAndCandies{
public:
int minBoxes(int C, int X, vector <int> low, vector <int> high){
int n=high.size();
sort(low.begin(),low.end(),cmp);
sort(high.begin(),high.end());
int ans1=n,ans2=n;
for (int i=0,t=0; i<n; ++i){
t+=low[i];
if (t>=X) {
ans1=i+1;
break;
}
}
for (int i=0,t=0; i<n; ++i){
t+=high[i];
if (C-t>=X){
ans2=n-i-1;
}
}
return min(ans1,ans2);
}
};
题目大意:
给定一张有向图,没有自环和重边。F(L)代表长度为L的路径总数,求最小的K使得当L趋近于无穷时,F(L)与L^K同阶。无解输出-1。
基本思路:如果图内没有环,则K一定为0。如果图内有一个强联通分量,且不是个简单环,则方案一定是指数级别的,所以无解。剩下的情况就是一些简单环之间通过边相连,如果把简单环当作点,把环之间的可达关系当作边,则就相当于是一张拓扑图。如果一条路径经过了C个简单环,则在分配在每个环上饶的圈数的方案和L^(C-1)同阶。由于我们只需要考虑同阶,所以简单环构成的拓扑图上的最长路C-1就是所求的K。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
bool f[55][55];
int parent[55], size_n[55],size_m[55] ;
int find(int x) {
if (parent[x] != x) parent[x] = find(parent[x]);
return parent[x];
}
int dp[55];
int n;
int dfs(int x) {
if (dp[x]) return dp[x];
int &ans = dp[x];
ans = 0;
for (int j = 0; j < n; ++j)
if (j != x && find(j) == j &&
f[j][x] && size_n[j] > 1) ans = max(ans, dfs(j));
return ans = ans + 1;
}
class BigO {
public:
int minK(vector <string> graph) {
n = graph.size();
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
f[i][j] = (graph[i][j] == 'Y');
for (int i = 0; i < n; ++i)
graph[i][i] = 1;
for (int k = 0; k < n; ++k)
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
f[i][j] |= f[i][k] & f[k][j];
for (int i = 0; i < n; ++i)
parent[i] = i;
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
if (f[i][j] && f[j][i])
parent[find(i)] = find(j);
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
if (graph[i][j] == 'Y' && find(i) == find(j))
++size_m[find(i)];
for (int i = 0; i < n; ++i)
++size_n[find(i)];
for (int i = 0; i < n; ++i)
if (size_m[find(i)] != size_n[find(i)] && size_n[find(i)] != 1) {
return -1;
}
memset(dp, 0, sizeof(dp));
for (int i = 0; i < n; ++i)
if (find(i) == i && size_n[i] > 1)
dfs(i);
int ans = 1;
for (int i = 0; i < n; ++i)
ans = max(ans, dp[i]);
return ans - 1;
}
};