真·玄学出奇迹
160暴力→220玄学成绩
简单说一说三四道题
(1)活动安排
求最多区间覆盖集
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
using namespace std;
inline int read(){
int i=0,f=1;
char ch;
for(ch=getchar();!isdigit(ch);ch=getchar())
if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar())
i=(i<<3)+(i<<1)+(ch^48);
return i*f;
}
int buf[1024];
inline void write(int x){
if(!x){putchar('0');return ;}
if(x<0){putchar('-');x=-x;}
while(x){buf[++buf[0]]=x%10,x/=10;}
while(buf[0]) putchar(buf[buf[0]--]+48);
return ;
}
#define stan 111111
struct aaa{
int s,t;
}a[stan];
int n,ed,ans;
bool cmp(aaa a,aaa b){
if(a.t!=b.t) return a.t<b.t;
else return a.s<b.s;
}
signed main(){
n=read();
for(int i=1;i<=n;++i){
a[i].s=read()*60+read();
a[i].t=read()*60+read();
}
sort(a+1,a+n+1,cmp);
ed=-1;
for(int i=1;i<=n;++i)
if(ed<=a[i].s)
++ans,ed=a[i].t;
write(ans);
return 0;
}
(2)最佳序列
二分平均值后单调队列判断平均值是否合法
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
#include<deque>
#define int long long
#define eps 1e-6
using namespace std;
inline int read(){
int i=0,f=1;
char ch;
for(ch=getchar();!isdigit(ch);ch=getchar())
if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar())
i=(i<<3)+(i<<1)+(ch^48);
return i*f;
}
int buf[1024];
inline void write(int x){
if(!x){putchar('0');return ;}
if(x<0){putchar('-');x=-x;}
while(x){buf[++buf[0]]=x%10,x/=10;}
while(buf[0]) putchar(buf[buf[0]--]+48);
return ;
}
#define stan 222222
int n,l,r;
double a[stan],sum[stan],ll,rr,mid;
bool check(double val){
for(int i=1;i<=n;++i)
sum[i]=a[i]-val;
for(int i=1;i<=n;++i)
sum[i]+=sum[i-1];
deque<int>que;
for(int i=l;i<=n;++i){
while(!que.empty()&&sum[que.back()]>sum[i-l]) que.pop_back();
que.push_back(i-l);
if(sum[i]>sum[que.front()]) return true;
while(!que.empty()&&que.front()<=i-r) que.pop_front();
}
return false;
}
signed main(){
n=read();l=read();r=read();
for(int i=1;i<=n;++i)
a[i]=read();
ll=0.0000;rr=1000000;
while(rr-ll>eps){
mid=(ll+rr)*0.5;
if(check(mid)) ll=mid;
else rr=mid;
}
printf("%.4f",(ll+rr)*0.5);
return 0;
}
(3)回文子串
其实是个
n4
DP,各种花式边界防炸
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
using namespace std;
inline int read(){
int i=0,f=1;
char ch;
for(ch=getchar();!isdigit(ch);ch=getchar())
if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar())
i=(i<<3)+(i<<1)+(ch^48);
return i*f;
}
int buf[1024];
inline void write(int x){
if(!x){putchar('0');return ;}
if(x<0){putchar('-');x=-x;}
while(x){buf[++buf[0]]=x%10,x/=10;}
while(buf[0]) putchar(buf[buf[0]--]+48);
return ;
}
#define stan 55
int f[stan][stan][stan][stan],len1,len2,a,b,c,d,ans;
char s[stan],t[stan];
signed main(){
scanf("%s%s",s+1,t+1);
len1=strlen(s+1);
len2=strlen(t+1);
for(register int i=1;i<=len1+1;++i)
for(register int j=1;j<=len2+1;++j)
for(register int k=len1;k>=0;--k)
for(register int l=len2;l>=0;--l){
a=i;b=j;c=k;d=l;
if(a<c&&(s[a]==s[c])&&f[a+1][b][c-1][d]<f[a][b][c][d]+2)
f[a+1][b][c-1][d]=f[a][b][c][d]+2;
if(b<d&&(t[b]==t[d])&&f[a][b+1][c][d-1]<f[a][b][c][d]+2)
f[a][b+1][c][d-1]=f[a][b][c][d]+2;
if(a<=c&&b<=d&&(s[a]==t[d])&&f[a+1][b][c][d-1]<f[a][b][c][d]+2)
f[a+1][b][c][d-1]=f[a][b][c][d]+2;
if(a<=c&&b<=d&&(t[b]==s[c])&&f[a][b+1][c-1][d]<f[a][b][c][d]+2)
f[a][b+1][c-1][d]=f[a][b][c][d]+2;
}
for(register int i=1;i<=len1+1;++i)
for(register int j=1;j<=len2+1;++j)
for(register int k=len1;k>=0;--k)
for(register int l=len2;l>=0;--l){
a=i;b=j;c=k;d=l;
if((a==c&&b>d)||(a>c&&b==d)) ans=max(ans,f[a][b][c][d]+1);
else if(a>c&&b>d) ans=max(ans,f[a][b][c][d]);
}
write(ans);
return 0;
}
(4)赌博游戏
比第三题简单
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
using namespace std;
inline int read(){
int i=0,f=1;
char ch;
for(ch=getchar();!isdigit(ch);ch=getchar())
if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar())
i=(i<<3)+(i<<1)+(ch^48);
return i*f;
}
int buf[1024];
inline void write(int x){
if(!x){putchar('0');return ;}
if(x<0){putchar('-');x=-x;}
while(x){buf[++buf[0]]=x%10,x/=10;}
while(buf[0]) putchar(buf[buf[0]--]+48);
return ;
}
#define stan 55
double f[stan*stan][stan][2],base;
int n,m,v,sum;
signed main(){
n=read();m=read();v=read();sum=read();
if(n==1){
if(v==sum){
puts("1.00000000");
return 0;
}else{
puts("0.00000000");
return 0;
}
}
for(int i=1;i<=m;++i)
if(i!=v) f[i][1][0]=1.0/m;
else f[i][1][1]=1.0/m;
for(int i=1;i<n;++i){
for(int j=1;j<=m*i;++j)
for(int k=1;k<=m;++k)
if(k!=v){
f[j+k][i+1][0]+=f[j][i][0]*1.0/m;
f[j+k][i+1][1]+=f[j][i][1]*1.0/m;
}else{
f[j+k][i+1][1]+=(f[j][i][0]+f[j][i][1])*1.0/m;
}
}
for(int i=1;i<=n*m;++i)
base+=f[i][n][1];
printf("%.8f",f[sum][n][1]/base);
return 0;
}