是计算抽中什么当期五星的期望。
现在的程序结果是99.6087
。结果不对,有时间再调。
#include
#include
typedef long long LL;
using namespace std;
int n = 90;
double p;
// double min_p = 1e-7;
double min_p = 0.0000000000000001;
vector<vector<double>> dp;
// x 0 保底、1 不保底
// y 0 必、1-89 不必
// acc 累计概率
// 返回抽到当期期望数
double dfs(int x, int y, double acc){
if(dp[x][y] != -1) return dp[x][y] + 1;
if(acc <= min_p) {
// TODO
cout << x << " " << y << " " << acc << " " << dp[x][y] << "==================" << endl;
return 1e18;
}
double g = 1;
if(x == 1 && y == 0){
dp[x][y] = 0.5 + 0.5 * dfs(0, 1, acc * 0.5);
} else if(x == 0){
dp[x][y] = p + (g-p) * dfs(0, (y+1) % n, acc * (g-p));
} else{
dp[x][y] = p/2 + (p/2) * dfs(0, (y+1) % n, acc * (p/2)) + (g-p) * dfs(1, (y+1) % n, acc * (g-p));
}
cout << x << " " << y << " " << acc << " " << dp[x][y] << endl;
// xxx: 注意!!!要加1
return dp[x][y] + 1;
}
int main() {
// int a, b;
// while (cin >> a >> b) { // 注意 while 处理多个 case
// cout << a + b << endl;
// }
freopen("D:\\auxiliaryPlane\\project\\scuCode\\input.txt","r",stdin);
freopen("D:\\auxiliaryPlane\\project\\scuCode\\output.txt","w",stdout);
// cin >> p;
p = 0.006;
// 输出 104.5497057
// 要求误差在1e-6内
dp = vector<vector<double>>(2, vector<double>(n, -1));
// 是否保底,连续没五次数 下次期望
// 估计一个当前概率阈值
dp[0][0] = 0;
cout << dfs(1, 1, 1);
// cout << 1;
// cout << min_p;
// printf("%.3f", min_p);
}
// 64 位输出请用 printf("%lld")
没调出来
#include
#include
using namespace std;
int n, m, a, b;
vector<bool> vis;
vector<vector<int>> team;
vector<vector<int>> stat;
vector<vector<int>> dp;
void maintain(vector<int> &arr){
int p = 0, n = arr.size();
for(int i=0;i<n;i++){
if(vis[arr[i]]) continue;
arr[p] = arr[i];
p++;
}
int t = n - p;
while(t--){
arr.pop_back();
}
}
void noABFind(){
maintain(stat[0]);
maintain(stat[1]);
maintain(stat[2]);
maintain(stat[3]);
// 根据vis和stat[0]维护dp
int emp = m-2;
dp = vector<vector<int>>(m-1, vector<int>());
for(auto &x: stat[0]){
if(vis[x]) continue;
for(int i=m-2;i>0;i--){
if(dp[i].size()) continue;
int p = i-team[x][0];
if(p >= 0){
if(p == 0 || dp[p].size()){
// dp[i] = dp[p];
for(auto t: dp[p]) dp[i].push_back(t);
dp[i].push_back(x);
emp--;
}
} else break;
}
if(emp == 0) break;
}
}
void output(vector<int> &x){
sort(x.begin(), x.end());
for(auto &y : x) {
vis[y] = true;
cout << y + 1 << " ";
}
cout << endl;
}
int main() {
// int a, b;
// while (cin >> a >> b) { // 注意 while 处理多个 case
// cout << a + b << endl;
// }
cin >> n >> m >> a >> b;
// 只要ab职业和总数不超就加,否则就向后找
vis = vector<bool>(n, false); // 用过 或 报名失败
team = vector<vector<int>>(n, vector<int>()); // 几个a,几个b,几个其他
stat = vector<vector<int>>(4, vector<int>());
for(int i=0;i<n;i++){
int t; cin >> t;
vector<int> arr = {0, 0, 0, 0};
for(int j=0;j<t;j++){
int jt; cin >> jt;
arr[0]++;
if(jt == a) arr[1]++;
else if(jt == b) arr[2]++;
else arr[3]++;
}
team[i] = arr;
if(arr[1] > 1 || arr[2] > 1) vis[i] = true;
if(arr[1] == 0 && arr[2] == 0) stat[0].push_back(i);
else if(arr[1] == 1 && arr[2] == 0) stat[1].push_back(i);
else if(arr[1] == 0 && arr[2] == 1) stat[2].push_back(i);
else stat[3].push_back(i);
}
for(int i=0;i<n;i++){
if(vis[i]) continue;
if(team[i][1] == 0 && team[i][2] == 0) continue;
// 以当前有ab的为首查找
vector<int> cnt = {team[i][0], team[i][1], team[i][2], team[i][3]};
vector<int> subans = {i};
noABFind();
if(cnt[1] == 1 && cnt[2] == 0){
// 先找有一个b的
for(auto &j : stat[2]){
if(vis[j]) continue;
int t = team[j][0] + cnt[0];
if(t > m) continue;
else if(t == m){
subans.push_back(j);
output(subans);
break;
} else if(dp[m - t].size() != 0){
subans.push_back(j);
subans.insert(subans.end(), dp[m-t].begin(), dp[m-t].end());
output(subans);
break;
}
}
} else if(cnt[1] == 0 && cnt[2] == 1){
for(auto &j : stat[1]){
if(vis[j]) continue;
int t = team[j][0] + cnt[0];
if(t > m) continue;
else if(t == m){
subans.push_back(j);
output(subans);
break;
} else if(dp[m - t].size() != 0){
subans.push_back(j);
subans.insert(subans.end(), dp[m-t].begin(), dp[m-t].end());
output(subans);
break;
}
}
} else{
int t = cnt[0];
if(t > m) continue;
else if(t == m){
output(subans);
} else if(dp[m - t].size() != 0){
subans.insert(subans.end(), dp[m-t].begin(), dp[m-t].end());
output(subans);
}
}
vis[i] = true;
}
}
// 只过了3.33%
// 8 6 1 2
// 4 1 2 3 3
// 1 1
// 1 1
// 1 3
// 5 3 3 3 4 2
// 4 4 5 6 2
// 1 1
// 1 1
// 64 位输出请用 printf("%lld")
有一些长度的木头数组woods[]
,用这些木头拼接length
,每根可取无限个,最少需要多少根木头,拼接不出返回-1。其中1<=len(woods)<=100
,1<=woods[i]<=1000
,1<=length<=10000
。样例(对你没看多,字符串格式的数组,自己解析,和4399一样):
输入:
[1, 2, 3, 5]
9
输出:
3
现有任务数组t1, t2, t3...tn
,每个数表示执行时间,长度为n
,现从中挑选k
个任务,并保持这k
个任务的顺序,将这k
个任务分隔为两部分,前一部分给A同学执行,后一部分给B同学执行,每个同学执行时间为任务时间之和,两位同学总时间为两人中的最大时间。问总时间最小是多少,询问T
组数据。其中1<=k<=n<=300000
,1<=ti<=10^9
,T组数据n的总和<=3 * 10^5
,样例:
输入:
2
10 6
10 8 18 13 3 8 6 4 14 12
10 5
9 9 2 11 14 33 4 9 14 12
输出:
21
18
有n个(105 )点的坐标(1~109),有两种点,红色0和蓝色1,每次可以进行两种操作:
最多进行第二种操作k次,问最少需要进行第一种操作多少次使得任意两个红色点之间没有蓝色点。
输入n、k、n个点坐标、n个点颜色
#include
typedef long long LL;
using namespace std;
LL maxx = 1e17 + 1;
int n, k;
vector<LL> x;
vector<bool> c;
vector<int> xr;
vector<int> xb;
// vector vis;
set<int> sset;
LL ans = maxx;
void cal(){
// 写暴力都很复杂啊
vector<int> tr = xr;
for(auto &i : sset){
tr.push_back(i);
}
sort(tr.begin(), tr.end());
vector<int> tb;
int last_b = -1;
int pb = 0, pr = 0;
// 还得过滤掉 三个蓝色点之间都没有红色点的那个中间蓝色点
while(pr < tr.size() && pb < xb.size()){
if(sset.count(xb[i])) {
pb++;
continue;
}
...
}
last_b = -1;
for(int i=1;i<xb.size();i++){
pb = xb[i];
LL subans = 0;
if(sset.count(xb[i])) continue;
if(last_b == -1){
last_b = i;
for(auto &j : tr){
if(j < pb) continue;
subans += x[j] - (x[pb] - 1);
}
} else{
for(auto &j : tr){
if(j < last_b) {
subans += x[last_b] + 1 - x[j];
} else if(j > pb){
subans += x[j] - (x[pb] - 1);
}
}
last_b = i;
}
ans = min(ans, subans);
}
// 最右边
...
ans = min(ans, subans);
}
void dfs(int p, int cnt){
if(cnt == k){
cal();
return ;
}
int m = xb.size();
if(m - p <= k - cnt){
for(int i=p;i<m;i++){
// vis[i] = true;
sset.insert(i);
}
cal();
for(int i=p;i<m;i++){
// vis[i] = false;
sset.erase(i);
}
return ;
}
dfs(p+1, cnt);
// vis[p] = true;
sset.insert(p);
dfs(p+1, cnt+1);
// vis[p] = false;
sset.erase(p);
}
int main(){
// 所有红点要连成一整片
cin >> n >> k;
x = vector<LL>(n);
c = vector<bool>(n);
for(int i=0;i<n;i++) cin >> x[i];
int sum = 0, l = -1, r = -1;
int cnt_blue = 0;
vector<int> xt;
for(int i=0;i<n;i++){
int t; cin >> t;
if(t == 0) {
c[i] = true;
r = x[i];
if(l != -1){
xb = xb.insert(xb.end(), xt.begin(), xt.end());
sum += cnt_blue;
cnt_blue = 0;
}
if(l == -1) l = x[i];
xr.push_back(i);
} else {
if(l != -1){
xt.push_back(i);
cnt_blue++;
}
c[i] = false;
}
}
// vis = vector(xb.size(), false);
if(sum <= k) {
cout << 0;
return 0;
}
// cout << 0; // 先拿点分
// 前i个蓝色的做了k次操作,这个太复杂了,记录状态,还要考虑新变成红色的。
// vector> dp(sum + 1, vector(k + 1, maxx));
// vector> last(sum + 1, vector(k + 1, -1));
// for(int i=1;i<=sum;i++){
// for(int j=0;j<=min(i+1, k);j++){
// }
// }
// 写暴力吧
dfs(0, 0);
cout << ans;
return 0;
}
#include
#include
using namespace std;
struct TireNode{
int ind;
TireNode* last;
vector next = vector(26);
TireNode(int ind){
ind = ind;
};
TireNode(int ind, TireNode* last) {
ind = ind;
last = last;
};
};
vector arr;
TireNode* root;
// void kmp(string par){
// int m = par.size();
// arr = vector(m + 1);
// if(m == 1) return ;
// // if(par[0] == par[1]) arr[1] = 1;
// for(int i=1;i 0 && par[j] != par[i]) j = arr[j];
// if(par[j] == par[i]) arr[i+1] = j + 1;
// else arr[i+1] = 0;
// }
// }
void kmp(string par, int index){
int m = par.size();
vector tt;
if(root->next[par[0] - 'a'] == nullptr){
TireNode* head = new TireNode(-1, root);
root->next[par[0] - 'a'] = head;
if(m == 1) {
head->ind = index;
return ;
}
} else{
if(m == 1){
root->next[par[0] - 'a']->ind = index;
return ;
}
}
tt.push_back(root->next[par[0] - 'a']);
for(int i=1;i 0 && par[j] != par[i]) j = arr[j];
// if(par[j] == par[i]) arr[i+1] = j + 1;
// else arr[i+1] = 0;
TireNode* j = tt[i];
while(j != root && )
}
}
int main() {
int n, q; cin >> n >> q;
string str; cin >> str;
root = new TireNode(0);
while(q--){
string t; cin >> t;
// int m = t.size();
// int cnt = 0;
// 暴力
// for(int i=0;i<=n-m;i++){
// bool flag = true;
// for(int j=0;j 0 && t[pt] != str[i]) pt = arr[pt];
// if(t[pt] == str[i]) pt++;
// else pt = 0;
// if(pt == m){
// cnt++;
// pt = arr[m];
// }
// }
// AC 自动机?
cout << cnt << endl;
}
return 0;
}
// 64 位输出请用 printf("%lld")