一.6月4日练习赛
A.NKOJ9887火柴棍
题意:用给定火柴棍摆出最小的数是多少,对998244853取模
先暴力打出来一个表,找规律:
n | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
ans | 1 | 7 | 4 | 2 | 0 | 8 | 10 | 18 | 22 | 20 | 28 | 68 | 88 | 108 | 188 | 200 | 208 | 288 | 688 | 888 | 1088 | 1888 | 2008 | 2088 |
可以发现,当n>=18时,ans[n]=ans[n-7]*10+8
正确性:由于8需要的火柴棍最多(7根),所以8是最好的消耗火柴棍的方式,所以是正确的
考场发现了规律,但是每一组数据都去算了一遍,没有想到预处理,最后TLE70
B.凸
原题:hihocoder#1596
题意:求随机打乱一个数组a,使得对于(2<=i<=n-1)的i,有ai-1+ai+1>=2*ai的总方案数
比赛的时候打的暴力搜索,实际上是一道dp题 下来看了题解觉得有点奇葩 四维的状态很难想
C.冠军联赛
没有来得及打暴力 给这道题分配的时间比较少 题也没有怎么想
D.彩色的树 Problem - 6035
题意:给定一棵树,每个节点有一个颜色值。定义每条路径的值为经过的节点的不同颜色数。求所有路径的值和。
这道题有人过了,所以想了一下,但是考试的时候觉得很难。
是一道树形DP题 ,练得很少 所以完全没有思路
总结一下第一场: 这场题很难 打的不是很好 一定要调好了再交 交题的机会很少。
二.6月11日模拟赛
A.签到题
确实是一道签到题 还给了SPJ 十分的善良
这种构造题 可以先判有没有解
易证:只有a1=a2=a3=.........=an时,才无解。
其次,构造就很简单了
由于双指针l和r再99.9%情况下是分别指向两个不同下标,所以可以利用双指针
a[i]!=l ,ans[i]=l a[i]!=r,ans[i]=r
注意:取到最后一个数时,l=r,将最后一个数往前面任意一个符合条件的位置放即可
B.翻转
题意:将被(1,1) (n,m)最短路框起来的数取反 求最少几次可以让0变为1
思路有两种
1.贪心:对于每一行的数 找最后一个1出现的位置 从上往下贪心
比赛的时候大概是这样的 但是细节问题WA33
2.DP:十分巧妙 可以将问题转化为(1,m)到(n,1)的最长路
最长路:对于a[i][j]和他的上一个点(a[i-1][j],a[i][j+1])不同时,路径长度+1
#include <bits/stdc++.h>
using namespace std;
int n,m;
int f[5005][5005];
char a[5005][5005];
int main () {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%s",a[i]+1);
for(int i=1;i<=m;i++) a[0][i]=a[1][i];
for(int i=1;i<=n;i++) a[i][m+1]=a[i][m];
for(int i=1;i<=n;i++)
for(int j=m;j>=1;j--)
f[i][j]=max(f[i-1][j]+((a[i][j]-'0')!=(f[i-1][j]&1)),f[i][j+1]+((a[i][j]-'0')!=(f[i][j+1]&1)));
printf("%d",f[n][1]);
return 0;
}
C.弹弹床
通过30%的数据 受到启发
设fij为前i个延伸出j条路的方案 当a[n]=R时,只能以n为终点,答案为f[n][1]
对于所有数据,再来一个g数组,表示后i个
ps:注意取模
#include <bits/stdc++.h>
using namespace std;
long long n,f[5005][5005],g[5005][5005],mod=1e9+7,q[5005];
char a[5005];
int main ()
{
scanf("%lld",&n);
if(n==1){printf("1");return 0;}
scanf("%s",a+1);
f[0][0]=g[n+1][0]=1,q[0]=1;
for(long long i=1;i<=n;i++) q[i]=(q[i-1]*i)%mod;
for(long long i=1;i<=n;i++)
{
for(long long j=1;j<=i;j++)
{
if(a[i]=='R')
{
f[i][j]=((f[i-1][j]*j)%mod+f[i-1][j-1])%mod;
}
else
{
f[i][j]=((f[i-1][j+1]*(j+1))%mod*j)%mod;
f[i][j]+=(f[i-1][j]*j%mod)%mod;
f[i][j]%=mod;
}
}
}
for(long long i=n;i>=1;i--)
{
for(long long j=1;j<=i;j++)
{
if(a[i]=='L')
{
g[i][j]=((g[i+1][j]*j)%mod+g[i+1][j-1])%mod;
}
else
{
g[i][j]=((g[i+1][j+1]*(j+1))%mod*j)%mod;
g[i][j]+=((g[i+1][j]*j)%mod);
g[i][j]%=mod;
}
}
}
for(long long i=1;i<=n;i++)
{
long long sum=0;
for(long long j=0;j+j+1<=n;j++)
{
sum+=(((q[j]*f[i-1][j])%mod)*((q[j+1]*g[i+1][j+1])%mod))%mod;
sum+=(((q[j]*g[i+1][j])%mod)*((q[j+1]*f[i-1][j+1])%mod))%mod;
sum+=((((((q[j]*f[i-1][j])%mod)*((q[j]*g[i+1][j])%mod))%mod)*2)%mod);
sum%=mod;
}
printf("%lld ",sum);
}
return 0;
}
D.博弈
同样通过部分分得到启发 只要有同色环就无解
但DP部分我还没有完全听懂 听懂了再补充一下
第二场总结一下 该拿的部分分还是拿到了 有一些贪心的思路要多多尝试一下
最后的总结:一定要保证每道题都想一下 有无解的不会做的尝试输出一下-1
dp题要开动脑筋,多见一些模型。
OI赛制下该拿的部分分要拿到!