20240324比赛总结
T1 卫星照片
https://gxyzoj.com/d/hzoj/p/3657
bfs暴力找联通块,再暴力判断即可
因为某些原因代码丢了,就不放了
T2 [luogu3802]小魔女帕琪
https://gxyzoj.com/d/hzoj/p/3656
考虑到,前7个均不同的概率为\(\prod_{i=1}^{7} \dfrac{a_i}{sum+1-i}\times 7!\)
因为每种情况均有\(\prod_{i=1}^{7} \dfrac{a_i}{sum+1-i}\)种,每个情况等概率出现,所以乘7!
接着考虑后面的情况,以第二个为例,方案数为:
化简得:\(\prod_{i=1}^{7} \dfrac{a_i}{sum+1-i}\times 7!\)
所以答案为:\(\prod_{i=1}^{7} \dfrac{a_i}{sum+1-i}\times 7!\times (sum-6)\)
代码:
#include<cstdio>
using namespace std;
int a[10],n;
double ans=1.0;
int main()
{
for(int i=1;i<=7;i++)
{
scanf("%d",&a[i]);
n+=a[i];
ans*=a[i]*i;
}
for(int i=0;i<=5;i++)
{
ans/=1.0*(n-i);
}
printf("%.3lf",ans);
return 0;
}
T3 [NOIP2016 普及组] 魔法阵
https://gxyzoj.com/d/hzoj/p/3655
设\(X_d-X_c=t\),则\(X_b-X_a=2t\)
因为\(X_b-X_a>(X_c-X_b)/3\),所以\(X_c-X_b>6t\),故\(X_c=X_b+6t+k\)
可以枚举\(t,k,X_d\),考虑优化
枚举\(X_d,t\),因为若\(X_a,X_b\)满足条件,则\(X_a-1,X_b-1\)一定满足,所以可以用前缀和记录\(X_a\times X_b\)即可
同理枚举\(X_a,t\),求\(ans_a,ans_b\)
代码:
#include<cstdio>
using namespace std;
int n,m,val[40004],cnt[15005],A[15005],B[15005],C[15005],D[15005];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d",&val[i]);
cnt[val[i]]++;
}
for(int t=1;t*9<=n;t++)
{
int sum=0;
for(int d=t*9+2;d<=n;d++)
{
int a=d-t*9-1;
int b=a+2*t;
int c=d-t;
sum+=cnt[a]*cnt[b];
C[c]+=sum*cnt[d];
D[d]+=sum*cnt[c];
}
sum=0;
for(int a=n-t*9-1;a>0;a--)
{
int b=a+2*t;
int d=a+t*9+1;
int c=b+6*t+1;
sum+=cnt[d]*cnt[c];
A[a]+=sum*cnt[b];
B[b]+=sum*cnt[a];
}
}
for(int i=1;i<=m;i++)
{
printf("%d %d %d %d\n",A[val[i]],B[val[i]],C[val[i]],D[val[i]]);
}
return 0;
}
T4 [HAOI2016] 字符合并
https://gxyzoj.com/d/hzoj/p/3298
看到数据范围,考虑区间dp+状压dp,设\(dp_{i,j,s}\)表示区间[i,j],合并后状态为s的最大值
因为最优的情况一定是将所有能合并的合并,且若暴力枚举断点,一定会T,考虑优化
1个字符可以不操作,m个连续字符可以合并成1个字符,于是得到\(x\times(m−1)+1\)个连续字符,能合并成一个字符。
所以,可以枚举所有能转移的点k求最大值,但当\((r-l)\equiv 0(\bmod m-1)\)时,要考虑\(dp_{l,r,0}=max(dp_{l,r,0}+w_s*[s=0])\),\(dp_{l,r,1}=max(dp_{l,r,1}+w_s*[s=1])\)
代码:
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
int n,m,a[305],c[305];
ll w[305],dp[305][305][305],g[5];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
for(int s=0;s<(1<<m);s++)
{
dp[i][j][s]=-2e9;
}
}
}
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
dp[i][i][a[i]]=0;
}
for(int i=0;i<(1<<m);i++)
{
scanf("%d%lld",&c[i],&w[i]);
}
for(int len=2;len<=n;len++)
{
for(int i=1;i+len-1<=n;i++)
{
int j=i+len-1;
int tmp=(len-1)%(m-1);
if(tmp==0&&len!=1) tmp=m-1;
for(int k=j;k>i;k=k-m+1)
{
for(int s=0;s<(1<<(tmp+1));s++)
{
dp[i][j][s<<1]=max(dp[i][k-1][s]+dp[k][j][0],dp[i][j][s<<1]);
dp[i][j][s<<1|1]=max(dp[i][k-1][s]+dp[k][j][1],dp[i][j][s<<1|1]);
}
}
if(tmp==m-1)
{
g[1]=g[0]=-2e9;
for(int s=0;s<(1<<m);s++)
{
g[c[s]]=max(g[c[s]],dp[i][j][s]+w[s]);
}
dp[i][j][0]=g[0],dp[i][j][1]=g[1];
}
}
}
ll ans=-9e18;
for(int i=0;i<(1<<m);i++)
{
ans=max(ans,dp[1][n][i]);
}
printf("%lld",ans);
return 0;
}