[P1005][NOIP2007] 矩阵取数游戏 (DP+高精)

我不会高精……

也不会DP……

这道题即考高精又考DP……

我要死了

给一个不是高精的代码(当然不能满分)

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=80+5;
const int maxl=32;
int n,m;
int a[maxn],f[maxn][maxn],aa[maxn],bb[maxn],ans[maxn];
int main()
{
    int ans=0;
    cin>>n>>m;
    for (int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++) scanf("%d",&a[j]);
        for(int j=1;j<=m;j++) f[j][j]=a[j];
        for(int j=1;j<=m-1;j++)
        {
            for(int k=1;k<=m-j;k++)
            {
                int l=k+j;
                f[k][l] = max(a[k]+2*f[k+1][l],a[l]+2*f[k][l-1]);
            } 
        }
        ans+=2*f[1][m];
    }
    cout<<ans<<endl;
    return 0;
} 
View Code

然后这个是AC代码

#include<stdio.h>
typedef long long ll;
ll MAX=1000000000000000;
struct bignum{ll p1,p2;};
bignum operator+(const bignum a,const bignum b){
    bignum c;
    c.p1=a.p1+b.p1;
    c.p2=a.p2+b.p2;
    if(c.p2>=MAX){
        c.p2-=MAX;
        c.p1++;
    }
    return c;
}
int operator<(const bignum a,const bignum b){
    if(a.p1<b.p1)return 1;
    if(a.p1>b.p1)return 0;
    if(a.p2<b.p2)return 1;
    return 0;
}
bignum pow2(int x){
    bignum a;
    a.p1=0;
    a.p2=1;
    while(x--)a=a+a;
    return a;
}
bignum operator*(const bignum a,const int b){
    bignum c;
    c.p1=a.p1*b;
    c.p2=a.p2*b;
    if(c.p2>=MAX){
        c.p1+=c.p2/MAX;
        c.p2%=MAX;
    }
    return c;
}
void  write(const bignum a){
    if(a.p1)printf("%lld%015lld",a.p1,a.p2);
    else printf("%lld",a.p2);
}
bignum max(const bignum a,const bignum b){
    return a<b?b:a;
}
int main(){
    int a[85],i,j,n,m;
    bignum score,f[85][85];
    score.p1=0;
    score.p2=0;
    scanf("%d%d",&n,&m);
    while(n--){
        for(i=1;i<=m;i++){
            scanf("%d",&a[i]);
            f[i][i]=pow2(m)*a[i];
        }
        for(j=1;j<m;j++)
            for(i=1;i<=m-j;i++)
                f[i][i+j]=max(f[i+1][i+j]+pow2(m-j)*a[i],f[i][i+j-1]+pow2(m-j)*a[i+j]);
        score=score+f[1][m];
    }
    write(score);
}

我实在是太菜了

只是为了过试炼场才去打恶心题的

最近发现了一个新的黑科技

__int128 貌似不用高精也可以过 而且速度也快

恶心啊,我一定要学__int128

#include<bits/stdc++.h>
#define in(x) x=read()
#define MAXN 81
#define k m-(R-L)
#define bll __int128

using namespace std;

inline int read() 
{
    int X=0,w=1;
    char ch=getchar();
    while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();
    return X*w;
}

int n,m;
int num[MAXN];
bll ans,p[MAXN],f[MAXN][MAXN];

bll dp(int L,int R)//记忆化搜索 
{
    if(f[L][R]!=-1) return f[L][R];
    if(R-L>=1) f[L][R]=max(num[L]*p[k]+dp(L+1,R),dp(L,R-1)+num[R]*p[k]);
    else f[L][R]=num[L]*p[k];
    return f[L][R];
}

void print(bll x)
{
    if(!x) return;
    if(x) print(x/10);
    putchar(x%10+'0');
}

int main()
{
    in(n);in(m);
    p[0]=1;
    for(int i=1;i<=m;i++) p[i]=p[i-1]*2;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++) in(num[j]);
        memset(f,-1,sizeof(f));
        ans+=dp(1,m);
    }
    if(!ans) printf("0");
    else print(ans);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/lincold/p/9774714.html