2021.08.30 膜你赛
2021.08.30 膜你赛
regular
Solution
Dp,设 \(f[i][j][k]\) 表示 插入i个括号,使用原序列j个括号,当前左括号比右括号多 k 个的数量的方案数。
Code
/*
* @Author: smyslenny
* @Date: 2021.08.30
* @Title:
* @Main idea:
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <vector>
#define int long long
#define INF 0x3f3f3f3f
#define orz cout<<"LKP AK IOI\n"
#define MAX(a,b) (a)>(b)?(a):(b)
#define MIN(a,b) (a)>(b)?(a):(b)
using namespace std;
const int mod=1e9+7;
const int M=205;
int n,len,sum[M];
char s[M];
int read()
{
int x=0,y=1;
char c=getchar();
while(c<'0' || c>'9') {if(c=='-') y=0;c=getchar();}
while(c>='0' && c<='9') { x=x*10+(c^48);c=getchar();}
return y?x:-x;
}
int sta[M];
namespace substack1{
int res,Ans;
void check()
{
int x=1;
for(int i=1;i<=n<<1;i++)
if(sta[i]==sum[x]) x++;
if(x>len) Ans++;
}
void dfs(int x,int res)
{
if(x>n*2)
{
if(res) return;
else check();
return;
}
if(res==0)
{
sta[x]=0;
dfs(x+1,res+1);
return;
}
sta[x]=1;
dfs(x+1,res-1);
sta[x]=0;
dfs(x+1,res+1);
}
void main()
{
for(int i=1;i<=len;i++) sum[i]=s[i]=='('?0:1;
dfs(1,0);
printf("%lld\n",Ans);
}
}
namespace substack2{
int f[M][M][M];
void main()
{
//f[i][j][k] 插入的括号的数量,使用的与序列的数量,当前左括号比右括号多 k 个的数量
f[0][0][0]=1;
for(int i=0;i<=2*n-len;i++)
for(int j=0;j<=len;j++)
for(int k=0;k<=n;k++)
{
if(s[j]=='(' && j<len)//当前是左括号并且当前序列中加入的括号数比原序列括号数小
f[i][j+1][k+1]=(f[i][j][k]+f[i][j+1][k+1])%mod;//加入这个左括号
else
f[i+1][j][k+1]=(f[i][j][k]+f[i+1][j][k+1])%mod;//当前是右括号,且左括号的数量大于右括号,插入一个左括号
if(k>0)
{
if(s[j]==')' && j<len)//如果是右括号,并且k>0,就将该右括号放入最终序列
f[i][j+1][k-1]=(f[i][j][k]+f[i][j+1][k-1])%mod;
else
f[i+1][j][k-1]=(f[i][j][k]+f[i+1][j][k-1])%mod;//当前枚举的是一个左括号,插入一个右括号
}
}
printf("%lld\n",f[2*n-len][len][0]);
}
}
signed main()
{
// freopen("regular.in","r",stdin);
// freopen("regular.out","w",stdout);
n=read();
scanf("%s",s+1);
len=strlen(s+1);
if(len==n<<1 && s[1]==')') printf("0\n");
else if(n<=10) substack1::main();
else substack2::main();
return 0;
}
number
Solution
\(2^n\) 的暴力。剩下的不回了。
/*
* @Author: smyslenny
* @Date: 2021.08.30
* @Title:
* @Main idea:
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <vector>
#define int long long
#define INF 0x3f3f3f3f
#define orz cout<<"LKP AK IOI\n"
#define MAX(a,b) (a)>(b)?(a):(b)
#define MIN(a,b) (a)>(b)?(a):(b)
using namespace std;
const int mod=998244353;
const int M=1005;
int n,m;
int read()
{
int x=0,y=1;
char c=getchar();
while(c<'0' || c>'9') {if(c=='-') y=0;c=getchar();}
while(c>='0' && c<='9') { x=x*10+(c^48);c=getchar();}
return y?x:-x;
}
struct ed{
int l,r,x;
}sz[M];
struct node{
int num,las[M],top;
}mp[M];
bool check()
{
for(int i=1;i<n;i++)
if(mp[i].num!=mp[i+1].num)
return false;
return true;
}
int js,Ans=INF;
void dfs(int x,int js)
{
if(x>m) return;
if(js>Ans) return;
if(check())
{
Ans=min(Ans,js);
return;
}
for(int i=sz[x].l;i<=sz[x].r;i++)
mp[i].las[++mp[i].top]=mp[i].num,mp[i].num=sz[x].x;
dfs(x+1,js+1);
for(int i=sz[x].l;i<=sz[x].r;i++)
mp[i].num=mp[i].las[mp[i].top],mp[i].top--;
dfs(x+1,js);
return;
}
signed main()
{
freopen("number.in","r",stdin);
freopen("number.out","w",stdout);
n=read(),m=read();
for(int i=1;i<=n;i++)
mp[i].num=i;
for(int i=1;i<=m;i++)
sz[i].l=read(),sz[i].r=read(),sz[i].x=read();
if(m>=1000)
{
printf("-1\n");
return 0;
}
dfs(1,0);
if(Ans==0) printf("-1\n");
else printf("%lld\n",Ans);
return 0;
}
sum
Solution
考试的时候只想到了 \(n^3\) 的暴力,现在优化到了 \(n^2\) ,但是不会做到 \(n\log n\) .
Code
/*
* @Author: smyslenny
* @Date: 2021.08.
* @Title:
* @Main idea:
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <vector>
#define ll long long
#define INF 0x3f3f3f3f
#define orz cout<<"LKP AK IOI\n"
#define MAX(a,b) (a)>(b)?(a):(b)
#define MIN(a,b) (a)>(b)?(a):(b)
using namespace std;
const int mod=998244353;
const int M=1e3+5;
int f[M];
int read()
{
int x=0,y=1;
char c=getchar();
while(c<'0' || c>'9') {if(c=='-') y=0;c=getchar();}
while(c>='0' && c<='9') { x=x*10+(c^48);c=getchar();}
return y?x:-x;
}
int n;
struct ed{
int u,v,net;
}edge[M<<1];
struct node{
int u,v;
}bian[M];
int head[M],num;
void addedge(int u,int v)
{
edge[++num].u=u;
edge[num].v=v;
edge[num].net=head[u];
head[u]=num;
}
int dfn[M],js,id[M],low[M];
void dfs(int u,int fa)
{
dfn[u]=++js;
f[u]=fa;
for(int i=head[u];i;i=edge[i].net)
{
int v=edge[i].v;
if(v==fa) continue;
dfs(v,u);
}
low[u]=js;
}
int Ans,fg[M];
int main()
{
n=read();
for(int i=1;i<n;i++)
{
int u=read(),v=read();
bian[i].u=u,bian[i].v=v;
addedge(u,v);
addedge(v,u);
}
dfs(1,0);
for(int i=1;i<n;i++)
{
int u=bian[i].u,v=bian[i].v;
if(f[u]==v) swap(u,v);
for(int j=dfn[v];j<=low[v];j++) fg[j]=1;
for(int k=1;k<=n;k++)
{
int x=k;int id_x=dfn[x],id_i=dfn[k];
while(x<=n)
{
id_x=dfn[x];
if(fg[id_x]==fg[id_i]) Ans++,x++;
else break;
}
}
for(int j=dfn[v];j<=low[v];j++) fg[j]=0;
}
printf("%d\n",Ans);
return 0;
}
本欲起身离红尘,奈何影子落人间。