社区讨论

不可思议

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 条回复,欢迎继续交流。

正在加载回复...