社区讨论
不可思议
P1005[NOIP 2007 提高组] 矩阵取数游戏参与者 5已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @mi6hjk5o
- 此快照首次捕获于
- 2025/11/20 04:59 4 个月前
- 此快照最后确认于
- 2025/11/20 04:59 4 个月前
随便打打,ac了:
CPP#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n,m,z,p[88][88],f[88][88][88],ans[88];
void cmp_max(int a,int b){
int tmpa[88],tmpb[88];
memset(tmpa,0,sizeof(tmpa));
memset(tmpb,0,sizeof(tmpb));
tmpa[0]=max(f[a-1][b+1][0],p[a-1][0]);
tmpb[0]=max(f[a][b+1][0],p[a+b][0]);
for(int x=1;x<=tmpa[0];x++){
tmpa[x]+=f[a-1][b+1][x]+p[a-1][x];
tmpa[x+1]+=tmpa[x]/10000;
tmpa[x]%=10000;
}
if(tmpa[ tmpa[0]+1 ])tmpa[0]++;
for(int x=1;x<=tmpb[0];x++){
tmpb[x]+=f[a][b+1][x]+p[a+b][x];
tmpb[x+1]+=tmpb[x]/10000;
tmpb[x]%=10000;
}
if(tmpb[ tmpb[0]+1 ])tmpb[0]++;
bool flag=false;
for(int x=max(tmpa[0],tmpb[0]);x>0;x--){
if(tmpa[x]>tmpb[x]) { flag=1; break; }
if(tmpb[x]>tmpa[x]) break;
}
if(flag){
for(int x=0;x<=tmpa[0];x++)
f[a][b][x]=tmpa[x];
}else{
for(int x=0;x<=tmpb[0];x++)
f[a][b][x]=tmpb[x];
}
return;
}
void add_mi(int a){
int divn=0;
for(int x=1;x<=p[a][0];x++){
p[a][x]=p[a][x]*2+divn;
divn=p[a][x]/10000;
p[a][x]%=10000;
}
if(divn){
p[a][0]++;
p[a][p[a][0]]=divn;
}
return;
}
void add_lst(int a){
f[a][0][0]=max(f[a][1][0],p[a][0]);
for(int x=1;x<=f[a][0][0];x++){
f[a][0][x]+=f[a][1][x]+p[a][x];
f[a][0][x+1]+=f[a][0][x]/10000;
f[a][0][x]%=10000;
}
if(f[a][0][ f[a][0][0]+1 ])f[a][0][0]++;
return;
}
bool cmp_ans(int a,int b){
for(int x=max(f[a][0][0],f[b][0][0]);x>0;x--){
if(f[a][0][x]<f[b][0][x])return true;
else if(f[b][0][x]<f[a][0][x])return false;
}
return false;
}
void add_ans(int a){
ans[0]=max(ans[0],f[a][0][0]);
for(int x=1;x<=ans[0];x++){
ans[x]+=f[a][0][x];
ans[x+1]+=ans[x]/10000;
ans[x]%=10000;
}
if(ans[ ans[0]+1 ])ans[0]++;
return;
}
int main(){
scanf("%d%d",&n,&m);
while(n--){
memset(f,0,sizeof(f));
memset(p,0,sizeof(p));
for(int i=1;i<=m;i++){
scanf("%d",&p[i][1]);
p[i][0]=1;
}
for(int k=m;k>0;k--){
for(int i=1;(i+k-1)<=m;i++){
cmp_max(i,k);
}
for(int i=1;i<=m;i++)add_mi(i);
}
for(int i=1;i<=m;i++)add_lst(i);
z=1;
for(int i=2;i<=m;i++)
if(cmp_ans(z,i))z=i;
add_ans(z);
}
printf("%d",ans[ans[0]]);
for(int i=(ans[0]-1);i>0;i--){
printf("%d",ans[i]/1000);
printf("%d",ans[i]/100%10);
printf("%d",ans[i]/10%10);
printf("%d",ans[i]%10);
}
return 0;
}
回复
共 4 条回复,欢迎继续交流。
正在加载回复...