题单传送门 26道题目
F
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e3+10;
int n,m,f[N][N];
string a,b;
void dfs(int i,int j){
if(i==0||j==0)return;
if(a[i]==b[j]){
dfs(i-1,j-1);
cout<<a[i];
}
else{
if(f[i][j-1]>=f[i-1][j])dfs(i,j-1);
else dfs(i-1,j);
}
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>a>>b;
int n=a.length(),m=b.length();
a=" "+a;
b=" "+b;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
f[i][j]=max(f[i-1][j],f[i][j-1]);
if(a[i]==b[j]){
f[i][j]=max(f[i][j],f[i-1][j-1]+1);
}
}
}
dfs(n,m);
}
J
有效打击的概率是 非 0 寿司数 / n 非0寿司数/n 非0寿司数/n
期望就是倒数
记录i,j,k分别表示寿司数为1,2,3的数目
i / ( i + j + k ) 的有效打击会用于寿司数为 1 上 i/(i+j+k)的有效打击会用于寿司数为1上 i/(i+j+k)的有效打击会用于寿司数为1上
j / ( i + j + k ) 的有效打击会用于寿司数为 2 上 j/(i+j+k)的有效打击会用于寿司数为2上 j/(i+j+k)的有效打击会用于寿司数为2上
k / ( i + j + k ) 的有效打击会用于寿司数为 3 上 k/(i+j+k)的有效打击会用于寿司数为3上 k/(i+j+k)的有效打击会用于寿司数为3上
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=301;
int n,a[4];
double f[N][N][N];
double dfs(int i,int j,int k){
if(i==0&&j==0&&k==0)return 0;
if(f[i][j][k]>0)return f[i][j][k];
double sum=1.0*n/(i+j+k);
if(i)sum+=dfs(i-1,j,k)*(1.0*i/(i+j+k));
if(j)sum+=dfs(i+1,j-1,k)*(1.0*j/(i+j+k));
if(k)sum+=dfs(i,j+1,k-1)*(1.0*k/(i+j+k));
return f[i][j][k]=sum;
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
int x;
cin>>x;
a[x]++;
}
printf("%.12lf",dfs(a[1],a[2],a[3]));
}
K
裸题sg博弈
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,k,a[110],f[N];
int dfs(int x){
if(f[x]!=-1)return f[x];
int ok=0;
for(int i=1;i<=n;i++){
if(x>=a[i])ok|=!dfs(x-a[i]);
}
return f[x]=ok;
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n>>k;
memset(f,-1,sizeof f);
f[0]=0;
for(int i=1;i<=n;i++)cin>>a[i],f[a[i]]=1;
if(dfs(k))cout<<"First";
else cout<<"Second";
}
L
记搜
d f s ( l , r , o p ) 表示我先手,我与对手的结果差值, dfs(l,r,op)表示我先手,我与对手的结果差值, dfs(l,r,op)表示我先手,我与对手的结果差值,
op=1表示要让结果最大化的那个先手者,op=0表示要让结果最小化的后手者
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e3+10;
int n,a[N],f[N][N][2];
int dfs(int l,int r,int op=1){
if(l==r)return a[l];
if(f[l][r][op]!=-1)return f[l][r][op];
if(op)return f[l][r][op]=max(a[l]-dfs(l+1,r,1-op),-dfs(l,r-1,1-op)+a[r]);
else return f[l][r][op]=max(a[l]-dfs(l+1,r,1-op),-dfs(l,r-1,1-op)+a[r]);
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n;
memset(f,-1,sizeof f);
int sum=0;
for(int i=1;i<=n;i++)cin>>a[i],sum+=a[i];
cout<<dfs(1,n);
}
M
f [ i ] [ j ] = ∑ f [ i − 1 ] [ j 到 j − a [ i ] ] f[i][j] = ∑f[i-1][j到j-a[i]] f[i][j]=∑f[i−1][j到j−a[i]]
记录一下前缀和就好了
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=1e9+7;
const int N=1e5+10;
int n,a[110],k;
int f[110][N],s[110][N];
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n>>k;
for(int i=1;i<=n;i++)cin>>a[i];
f[0][0]=1;
int i=0;
s[i][0]=f[i][0];
for(int j=1;j<=k;j++){
s[i][j]=(s[i][j-1]+f[i][j])%mod;
}
for(int i=1;i<=n;i++){
for(int j=0;j<=k;j++){
int r=j;
int l=j-a[i];
if(l<=0)f[i][j]=s[i-1][r];
else f[i][j]=s[i-1][r]-s[i-1][l-1];
f[i][j]=(f[i][j]+mod)%mod;
}
s[i][0]=f[i][0];
for(int j=1;j<=k;j++){
s[i][j]=(s[i][j-1]+f[i][j])%mod;
}
}
cout<<f[n][k];
}