[P1005][NOIP2007] 矩阵取数游戏 (DP+高精)
我不会高精……
也不会DP……
这道题即考高精又考DP……
我要死了
给一个不是高精的代码(当然不能满分)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }
然后这个是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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }