Educational Codeforces Round 170 (Rated for Div. 2)
ABC 略
ABC 略
D
n较大,m较小,我们以m为研究对象枚举每个0的位置选择哪个属性,f[i][j]表示第i个0之前有j个选择X的最大收益。这样设计状态的好处是可以将非0部分的满足情况一段一段考虑,即两个0之间的数是否被满足仅有前面的0决定。f[i][j]=max(f[i-1][j],f[i-1][j-1])+这一个0到上一个0中<=j的正数和>=i-1-j的负数的个数。后者可以用前缀和维护小于这个数前缀和的数的个数。
#include<bits/stdc++.h>
using namespace std;
//#define int long long
const int N=2e6+10;
int T,n,m,a[N],f[5010][5010],b[5010],cnt,ans,zz[N],ff[N],zzz[N],fff[N];
void init()
{cnt=ans=0;
}
void solve()
{cin>>n>>m;init();for(int i=1;i<=n;i++){cin>>a[i];if(a[i]==0) b[++cnt]=i,zz[i]=5001,ff[i]=5001;else if(a[i]<0) ff[i]=-a[i],zz[i]=5001;else zz[i]=a[i],ff[i]=5001;}b[++cnt]=n+1;for(int i=2;i<=cnt;i++){for(int j=0;j<=m;j++) fff[j]=zzz[j]=0;for(int j=b[i-1]+1;j<=b[i]-1;j++) fff[ff[j]]++,zzz[zz[j]]++;for(int j=2;j<=cnt;j++) fff[j]+=fff[j-1],zzz[j]+=zzz[j-1];for(int j=0;j<i;j++){f[i][j]=max(f[i-1][j],f[i-1][j-1])+fff[j]+zzz[i-1-j];}}for(int i=0;i<cnt;i++) ans=max(ans,f[cnt][i]);cout<<ans<<endl;
}
signed main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie();//cin>>T;T=1;while(T--) solve();
}
E
根据题意找到三个性质,在相同花色的牌相消后
1.花色为1的如果有剩余,只能是A
2.花色不为1的如果有剩余,只能是B
3.花色为1的A的剩余的和花色不为1的B的剩余的数量相同
我们只要算出花色为1 m张牌从0~m的剩余情况乘上2~n个花色中对应剩余的情况数取最大值即可。
f[i][j]代表花色为1的前i大的牌A比B多j张牌的方案数。因为相同花色下B打的牌A必须打出等级更高的,所以枚举i时,j非负。转移为f[i][j]=f[i-1][j-1]+f[i-1][j+1]分别代表等级为j的牌分为A还是B。
g[i][j]代表2~i个花色B比A多选j个的方案数,我们枚举i从2~n,枚举j从0到m,k从0到j,因为每个花色的j只能递增。g[i][j]=g[i][j]+g[i-1][k]*f[m][j-k].代表2~i-1层B比A多k个的方案数*第i层B新增的比A多出的j-k个的方案数,后者在第一步已经算出。
答案就是g[n][i]*f[m][i]的最大值
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e3+10,mod=998244353;
int T,n,m,f[N][N],g[N][N],ans;
void init()
{
}
void solve()
{cin>>n>>m;init();f[0][0]=1;for(int i=1;i<=m;i++){f[i][0]=f[i-1][1];for(int j=1;j<=m;j++){f[i][j]=(f[i-1][j-1]+f[i-1][j+1])%mod;}}g[1][0]=1;/*for(int i=2;i<=n;i++){for(int j=0;j<=m;j++){for(int k=j;k<=m;k++){g[i][k]=(g[i][k]+g[i-1][k-j]*f[m][j])%mod;}}}*/for(int i=2;i<=n;i++){for(int j=0;j<=m;j++){for(int k=0;k<=j;k++){g[i][j]=(g[i][j]+g[i-1][k]*f[m][j-k])%mod;}}}for(int i=0;i<=m;i++)ans=(ans+g[n][i]*f[m][i])%mod;cout<<ans<<endl;
}
signed main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie();//cin>>T;T=1;while(T--) solve();
}