码迷,mamicode.com
首页 > 其他好文 > 详细

bign+dp 矩阵取数

时间:2014-07-23 12:02:56      阅读:234      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   for   re   c   

状态转移方程可以直接用dp[i][j]=max(dp[i+1,j]+a[i],dp[i,j-1]+a[j])*(2^k)),但是还要算2^k次方,可以先用数组储存2的方幂,但不可避免高精度乘法,如果只是*2的话可以用加法代替

逆向思考,自内而外,用f[i,j]表示从i取到j的最大值,状态转移方程便为f[i,j]:=max(f[i+1,j]+a[i],f[i,j-1]+a[j])*2 ,相当于每到下一层都把上一层乘了2,越在内层,乘2的次数越多,这样我们就免于高精度乘法了

简略代码如下:

struct bigint {int a[40];};
int m,n;
bigint a[81],res,f[81][81],k1,k2;

bigint add(bigint k,bigint l)
{
    bigint j;
    memset(j.a, 0, sizeof(j.a));
    for(int i=1;i<=k.a[0]||i<=l.a[0];i++) j.a[i]=k.a[i]+l.a[i];
    j.a[0]=k.a[0]>l.a[0]?k.a[0]:l.a[0];
    for(int i = 1; i <= j.a[0]; i++){
        j.a[i+1]+=j.a[i]/10;
        j.a[i]%=10;
    }
    if(j.a[j.a[0]+1]>0)    j.a[0]++;
    return j;
}
////////////////////////////////////////////////////////////
bigint cmp(bigint k,bigint l)
{
    if(k.a[0]>l.a[0]) return k;
    if(k.a[0]<l.a[0]) return l;
    if(k.a[0]==l.a[0]) for(int i=k.a[0];i>=1;i--){
        if(k.a[i]>l.a[i]) return k;
        if(k.a[i]<l.a[i]) return l;
    }
    return l;
}
//////////////////////////////////////////////////////////////
void init()
{
    memset(a,0,sizeof(a));
    for(int i=1;i<=m;i++){
        scanf("%d",&a[i].a[1]);
        a[i].a[0]=1;
        while(a[i].a[a[i].a[0]]>=10)
        {//a[0]表示a的位数,将输入的存在[1]中的数分散到a[1,2..]中去 
            a[i].a[a[i].a[0]+1]=a[i].a[a[i].a[0]]/10;
            a[i].a[a[i].a[0]]%=10;
            a[i].a[0]++;
        }
    }
}
/////////////////////////////////////////////////////////////
void solve()
{
    memset(f,0,sizeof(f));
    for(int i=1;i<=m;i++) f[i][i]=add(a[i],a[i]);
    for(int i=m;i>=1;i--)
        for(int j=i+1;j<=m;j++){
            k1=add(f[i+1][j],a[i]);
            k2=add(f[i][j-1],a[j]);
            f[i][j]=cmp(k1,k2);
            f[i][j]=add(f[i][j],f[i][j]);
        }
    res=add(res,f[1][m]);
}
/////////////////////////////////////////////////////////////
int main()
{
    scanf("%d%d",&n,&m);
    res.a[0]=1;
    for(int i=1;i<=n;++i){
        init();
        solve();
    }
    //output 
    for (int i=res.a[0];i>0;i--) 
        printf("%d",res.a[i]);
    cout<<endl;
     return 0;
}

bign+dp 矩阵取数,布布扣,bubuko.com

bign+dp 矩阵取数

标签:style   blog   color   for   re   c   

原文地址:http://www.cnblogs.com/tinyork/p/3862120.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!