20230415小记
废话
上语文课,听了一节鲁迅的《祝福》。然后我的Zah和lzy都深深共情,我只感受到了一种如坠深渊的无力感...
磕同桌和她学长的cp真的太爽了
同桌太可爱了怎么办
如何不被同桌掰弯
可是 真的 好可爱。!!!
CF464D World of Darkraft - 2
题目大意:
一款游戏中有 \(k\) 种装备,你一开始每种装备各有 \(1\) 个,且每种装备的初始等级均为 \(1\)。游戏中可以靠打怪来获取新装备,总共有 \(n\) 只怪兽,每打赢 \(1\) 只怪兽后会随机获得一种装备 \(a \in [1,k]\)。假设原有的 \(a\) 装备的等级为 \(t\),那么新获得的装备的等级为 \([1,t+1]\),且你会将新获得的装备和原来的装备中等级较高的装备留下,等级较低的装备卖出,卖出可获得的金币为该装备的等级。 问打完这 \(n\) 只怪兽后,获得的金币的期望。
\(1 \le n \le 10^5, 1 \le k \le 100\)
sol:
首先可以求出来一个的然后把答案*k。
\(dp_{i,j}\) 表示还有i个怪,目前等级为j。
朴素的trick,但是第一次看到qwq。
为什么是 还剩 i 个怪兽,而不是打了 i 个怪兽呢?因为如果我们如果设计是打了 i 个怪兽的话,每次往后转移的时候还要考虑到这种情况出现的概率,不好处理。而如果从后往前转移的话,就避免了复杂的计算。
--from paulzrm
转移柿子是好推的。
然后考虑到答案是小数,有些东西可以忽略,取一个max_level=1000,就完事了。
#include<bits/stdc++.h>
using namespace std;
double n,k;
double dp[2][1005];
int main(){
cin>>n>>k;
int now=0,pre=1;
for(int i=1;i<=n;i++,now^=1,pre^=1){
for(int j=1;j<=1000;j++){
dp[now][j]=0;
dp[now][j]+=dp[pre][j] *(k-1.0)/k;
dp[now][j]+=(dp[pre][j]+(j+1.0)/2.0) *j/k/(j+1);
dp[now][j]+=(dp[pre][j+1]+j) /k/(j+1.0);
}
}
double tmp=dp[pre][1]*k;
printf("%.10lf",tmp);
return 0;
}
打了场CF...掉大分 为什么我这么菜
CF1820A Yura's New Name
要求保证每个_旁边都有^ ,一定一定细心读题看样例
CF1820B JoJo's Incredible Adventures
题意先转化成求最长连续的1,然后用这些1构成矩形
CF1820C Constructive Problem
大分讨,注意在讨论大的case的时候注意小的case,(尤其是调代码的时候)之后的讨论不要覆盖之前的讨论。
CF494C Helping People
呜呜,读错题了qwq。血淋淋的教训是看完题一定一定手玩一下样例
首先写一个朴素的trick:保证区间不会交错,即仅能有并列关系和包含关系,这个线段形成一个树形结构。
然后写一下sol:
首先简单的dp就是\(dp_{i,j}\)表示第i个询问时max小于等于j的概率。这是一个期望常见的设法。(但我不会)大概是因为偏序关系比起相等关系总是更容易满足的。
j是大的,这复杂度非常垃圾。考虑到每次的\(\Delta max \le 1\),总的\(\Delta max \le q\),就用变化量dp,然后就得到了一个可以做的式子。
复杂度\(O(n\log_n+q^2)\).
//#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5,Q=5e3+5;
struct Query_{
int l,r,ma;double p;
bool operator < (const Query_ x){
if(l==x.l) return r>x.r;
return l<x.l;
}
}q[Q];
double dp[Q][Q];
int n,m,a[N];
class RMQ{
private:
int ma[N][20],lg[N];
public:
void init(){
for(int i=2;i<=n;i++) lg[i]=lg[i>>1]+1;
for(int i=1;i<=n;i++) ma[i][0]=a[i];
for(int i=1;(1<<i)<=n;i++){
int len=1<<i,l=1<<(i-1);
for(int j=1;j+len-1<=n;j++)
ma[j][i]=max(ma[j][i-1],ma[j+l][i-1]);
}
return ;
}
int query(int l,int r){
return max(ma[l][lg[r-l+1]],ma[r-(1<<lg[r-l+1])+1][lg[r-l+1]]);
}
}R;
vector<int> v[N];
void dfs(int u){
double np=q[u].p;
dp[u][0]=1.0-np;
// cout<<u<<" "<<np<<endl;
for(int to:v[u]) dfs(to);
for(int to:v[u]) dp[u][0]*=dp[to][q[u].ma-q[to].ma];
for(int i=1;i<=m;i++){
double p1=1,p2=1;
for(int to:v[u]){
p1*=dp[to][min(i+q[u].ma-q[to].ma-1,m)];
p2*=dp[to][min(i+q[u].ma-q[to].ma,m)];
}
dp[u][i]=np*p1+(1.0-np)*p2;
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
R.init();
for(int i=1;i<=m;i++){
int l,r;double pp;
cin>>l>>r>>pp;
q[i]=(Query_){l,r,R.query(l,r),pp};
}
q[++m]=(Query_){1,n,R.query(1,n),0.0};
sort(q+1,q+m+1);
for(int i=2;i<=m;i++)
for(int j=i-1;;j--)
if(q[i].l>=q[j].l&&q[i].r<=q[j].r){
v[j].push_back(i);
// cout<<j<<" "<<i<<" "<<q[i].l<<" "<<q[i].r<<" "<<q[i].ma<<endl;
break;
}
dfs(1);
double ans=q[1].ma;
for(int i=1;i<=m;i++) ans+=(double)(dp[1][i]-dp[1][i-1])*i;
// for(int i=0;i<=m;i++) cout<<i<<" "<<dp[1][i]<<endl;
// for(int i=0;i<=m;i++) cout<<"2 :"<<i<<" "<<dp[2][i]<<endl;
// for(int i=0;i<=m;i++) cout<<"3 :"<<i<<" "<<dp[3][i]<<endl;
printf("%.9lf",ans);
return 0;
}
/*
RMQ写错了/cy
*/