思路:
二分 + D F S DFS DFS + 剪枝
总体思路如下:
剪枝:
代码如下:
#include
#define fast ios::sync_with_stdio(false), cin.tie(nullptr); cout.tie(nullptr)
#define x first
#define y second
#define int unsigned int
using namespace std;
typedef pair<int, int> PII;
const int N = 55, M = 1010, null = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;
int n, m;
int big[N], small[M], sum_small[M];
int sum_big;
int waste;
int mid;
bool dfs(int k, int now)
{
if(k == 0) return true; // 成立
if(sum_big - waste < sum_small[mid]) return false; // 3. 可行性剪枝
bool f = 0;
for (int i = now; i <= n; i ++ )
{
if(big[i] >= small[k])
{
big[i] -= small[k];
if(big[i] < small[1]) waste += big[i];
if(small[k - 1] == small[k]) f = dfs(k - 1, i); // 4. 排除等效冗余
else f = dfs(k - 1, 1);
// 恢复现场
if(big[i] < small[1]) waste -= big[i];
big[i] += small[k];
if(f) return true;
}
}
return false;
}
void solve()
{
cin >> n;
for (int i = 1; i <= n; i ++ )
cin >> big[i], sum_big += big[i];
sort(big + 1, big + n + 1);
cin >> m;
for (int i = 1; i <= m; i ++ )
cin >> small[i];
sort(small + 1, small + m + 1);
for (int i = 1; i <= m; i ++ )
sum_small[i] = sum_small[i - 1] + small[i];
while(sum_small[m] > sum_big) m --; // 2. 可行性剪枝
int l = 0, r = m;
while(l < r)
{
mid = l + r + 1>> 1;
if(dfs(mid, 1)) l = mid; // 1. 优化搜索顺序
else r = mid - 1;
}
cout << l << endl;
return;
}
signed main()
{
fast;
int T = 1;
//cin >> T;
while(T -- )
solve();
return 0;
}
思路:
二分答案
代码如下:
#include
#define fast ios::sync_with_stdio(false), cin.tie(nullptr); cout.tie(nullptr)
#define x first
#define y second
#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N = 55, M = 1010, null = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;
int n, m;;
int a[N];
bool check(int x)
{
int res = 0;
int s = min(x, m);
for (int i = 1; i <= n; i ++ )
{
if(a[i] < x) res += x - a[i];
if(res > s) return false;
}
return true;
}
void solve()
{
cin >> n >> m;
for (int i = 1; i <= n; i ++ )
cin >> a[i];
int l = 1, r = 1e9;
while(l < r)
{
int mid = l + r + 1 >> 1;
if(check(mid)) l = mid;
else r = mid - 1;
}
cout << l << endl;
return;
}
signed main()
{
fast;
int T = 1;
//cin >> T;
while(T -- )
solve();
return 0;
}
思路:
二分答案
代码如下:
#include
#define fast ios::sync_with_stdio(false), cin.tie(nullptr); cout.tie(nullptr)
#define x first
#define y second
#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N = 50010, M = 1010, null = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;
int n, m, len;
int a[N];
bool check(int x)
{
int res = 0;
int last = 0;
for (int i = 1; i <= n; i ++ )
{
if(a[i] - a[last] < x) res ++;
else last = i;
if(res > m) return false;
}
return true;
}
void solve()
{
cin >> len >> n >> m;
for (int i = 1; i <= n; i ++ )
cin >> a[i];
int l = 0, r = len;
while(l < r)
{
int mid = l + r + 1 >> 1;
if(check(mid)) l = mid;
else r = mid - 1;
}
cout << r << endl;
return;
}
signed main()
{
fast;
int T = 1;
//cin >> T;
while(T -- )
solve();
return 0;
}
思路:
浮点数二分答案:
代码如下:
#include
#define fast ios::sync_with_stdio(false), cin.tie(nullptr); cout.tie(nullptr)
#define x first
#define y second
#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N = 50010, M = 1010, null = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;
int n, m, len;
int a[N];
bool check(double x)
{
double atime = x / m + (len - x) / n;
double bt = x / m + (x - x / m * n) / (m + n) ;
double btime = bt + (len - bt * n) / m;
//cout << atime << " " << btime << endl;
if(btime > atime) return true;
else return false;
}
void solve()
{
scanf("%d%d%d", &len, &n, &m);
double l = 0, r = len;
while( fabs(l - r) > eps )
{
double mid = (l + r) / 2;
if(check(mid)) r = mid;
else l = mid;
}
double res = l / m + (len - l) / n;
printf("%.2lf\n", res);
return;
}
signed main()
{
//fast;
int T = 1;
//cin >> T;
while(T -- )
solve();
return 0;
}
思路:
浮点数二分答案:
代码如下:
#include
#define fast ios::sync_with_stdio(false), cin.tie(nullptr); cout.tie(nullptr)
#define x first
#define y second
#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N = 10010, M = 1010, null = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-9;
int n, m, len;
double a[N];
bool check(double x)
{
int res = 0;
for (int i = 1; i <= n; i ++ )
{
res += floor(a[i] / x);
}
if(res >= m) return true;
else return false;
}
void solve()
{
scanf("%lld %lld", &n, &m);
for (int i = 1; i <= n; i ++ )
scanf("%lf", &a[i]);
double l = 0, r = 1e9;
while( fabs(r - l) > eps )
{
double mid = (l + r) / 2;
if(check(mid)) l = mid;
else r = mid;
}
printf("%.6f\n", r);
return;
}
signed main()
{
//fast;
int T = 1;
//cin >> T;
while(T -- )
solve();
return 0;
}
思路:
二分答案
代码如下:
#include
#define fast ios::sync_with_stdio(false), cin.tie(nullptr); cout.tie(nullptr)
#define x first
#define y second
#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N = 5e5 + 10, M = 1010, null = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-9;
int n, m1, m2;
int a[N];
bool check(int x)
{
int res = 0;
for (int i = 1; i <= n; i ++ )
{
int j = a[i] - m1 * x;
if(j > 0) res += j / m2 + (j % m2 != 0);
if(res > x) return false;
}
return true;
}
void solve()
{
cin >> n >> m1 >> m2;
for (int i = 1; i <= n; i ++ )
cin >> a[i];
int l = 1, r = 1e9;
while(l < r)
{
int mid = l + r >> 1;
if(check(mid)) r = mid;
else l = mid + 1;
}
cout << r << endl;
return;
}
signed main()
{
//fast;
int T = 1;
//cin >> T;
while(T -- )
solve();
return 0;
}