随机序列
Problem
给出两个长度均为
-
中,所有数都是 之间的整数; -
所有正整数在
和 中的出现次数加起来不超过 ;
在此基础上,设
要求返回使得
Input
第一行一个正整数
第二行个整数,代表数组
第三行个整数,代表数组
第四行一个正整数,代表
Output
输出仅一行,一个小数
精度误差在
Sample
Input 1
4
0 2 7 0
6 3 8 10
12
Output 1
0.4375
Solution
由于
同时,
可以采用二进制优化,但我选择使用
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<bitset>
#include<iomanip>
using namespace std;
const int kmax = 55;
int n, k, a[kmax], b[kmax];
int w[kmax], c;
int res = -1e9;
bitset<kmax * kmax> f[kmax];
int main() {
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> a[i];
k += !a[i]; // 计算有多少个0
}
for(int i = 1; i <= n + 1; i++) {
cin >> b[i];
}
b[n + 1]++; // 右闭区间转开区间
sort(b + 1, b + n + 1); // 排序
for(int i = 1; i <= n; i++) {
w[i] = min(b[i + 1], b[n + 1]) - b[i] - 1; // 求区间
for(int j = 1; j <= n; j++) {
if(a[j] > b[i]) c++; // 计算原先有多少对
if(b[i] < a[j] && a[j] < b[i + 1]) w[i]--; // a中原先的数不能选
}
}
for(int i = 0; i <= k; i++) {
f[i][c] = 1; // 初始化
}
for(int i = 1; i <= n; i++) { // 多重背包
for(int j = 1; j <= w[i] && j <= k; j++) {
for(int l = k - 1; l >= 0; l--) {
f[l + 1] |= f[l] << i; // bitset 转移
}
}
}
for(int i = 0; i <= n * n; i++) {
if(!f[k][i]) continue; // 该状态无法实现
if(abs(n * n - 2 * res) <= abs(n * n - 2 * i)) continue; // 不够优
res = i;
}
cout << fixed << setprecision(9) << 1.0 * res / n / n << '\n';
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】