NOIP2007矩阵取数游戏

来源:互联网 发布:淘宝售假怎么投诉 编辑:程序博客网 时间:2024/05/16 01:49

题目来源:https://www.luogu.org/problem/show?pid=1005


dp并不难,f[i][j]表示从i到j的最大得分,f[i][j]=max(f[i+1][j]+a[i]*2^k,f[i][j-1]+a[j]*2^k)。


由于数据较大需要用到高精。


long long 60分代码:


#include <algorithm>#include <iostream>#include <cstring>#include <cstdlib>#include <sstream>#include <cstdio>#include <string>#include <vector>#include <cmath>#include <ctime>#include <stack>#include <queue>#include <set>#include <map>using namespace std;long long a[81][81]={0};long long f[81][81]={0};long long _pow(long long a,long long b){    if(b==1)return a;    if(b==0)return 1;    int c=_pow(a,b/2);    if(b%2==0)return c*c;    else return c*c*a;}int main(){    ios::sync_with_stdio(false);    long long n,m;    cin>>n>>m;    for(int i=1;i<=n;i++)    {        for(int j=1;j<=m;j++)        {            cin>>a[i][j];        }    }    long long sum=0;    for(long long k=1;k<=n;k++)    {        memset(f,0,sizeof(f));        for(long long i=1;i<=m;i++)        {            for(long long j=m;j>=1;j--)            {                if(j>=i)                {                    if(i-1>=1)f[i][j]=max(f[i][j],f[i-1][j]+a[k][i-1]*_pow(2,m-j+i-1));                    if(j+1<=m)f[i][j]=max(f[i][j],f[i][j+1]+a[k][j+1]*_pow(2,m-j+i-1));                }            }        }        long long tot=0;        for(int i=1;i<=m;i++)tot=max(tot,f[i][i]+_pow(2,m)*a[k][i]);        sum+=tot;    }    cout<<sum;    return 0;}


使用高精度模板,100分代码:


#include <algorithm>#include <iostream>#include <cstring>#include <cstdlib>#include <sstream>#include <cstdio>#include <string>#include <vector>#include <cmath>#include <ctime>#include <stack>#include <queue>#include <set>#include <map>using namespace std;const int maxn=200;struct bignumber{    int len,s[maxn];    bignumber(){memset(s,0,sizeof(s));len=1;}    bignumber operator = (const char* num)    {        len=strlen(num);        for(int i=0;i<len;i++)s[i]=num[len-i-1]-'0';        return *this;    }    bignumber operator = (const int num)    {        char a[maxn];        sprintf(a,"%d",num);        *this=a;        return *this;    }    bignumber(const int num){*this=num;}    bignumber(const char* num){*this=num;}    bignumber operator + (const bignumber& a)    {        bignumber c;        c.len=max(len,a.len)+1;        for(int i=0,x=0;i<c.len;i++)        {            c.s[i]=s[i]+a.s[i]+x;            x=c.s[i]/10;            c.s[i]%=10;        }        if(c.s[c.len-1]==0)c.len--;        return c;    }    bignumber operator += (const bignumber& a)    {        *this=*this+a;        return *this;    }    bignumber operator * (const bignumber& x)    {        bignumber c;        c.len=len+x.len;        for(int i=0;i<len;i++)        {            for(int j=0;j<x.len;j++)            {                c.s[i+j]+=s[i]*x.s[j];                c.s[i+j+1]+=c.s[i+j]/10;                c.s[i+j]%=10;            }        }        if(c.s[c.len-1]==0)c.len--;        return c;    }    bignumber operator *= (const bignumber& a)    {        *this=*this*a;        return *this;    }    bool operator < (const bignumber& x)const    {        if(len!=x.len)return len<x.len;        for(int i=len-1;i>=0;i--)        {            if(s[i]!=x.s[i])return s[i]<x.s[i];        }        return false;    }    bool operator > (const bignumber& x)const{return x<*this;}    bool operator <= (const bignumber& x)const{return !(x<*this);}    bool operator >= (const bignumber& x)const{return !(*this<x);}    bool operator == (const bignumber& x)const{return !(x<*this||*this<x);}    bool operator != (const bignumber& x)const{return x<*this||*this<x;}};ostream& operator << (ostream& out,const bignumber& x){    for(int i=x.len-1;i>=0;i--)cout<<x.s[i];    return out;}istream& operator >> (istream& in,bignumber& x){    char num[maxn];    in>>num;    x=num;    return in;}bignumber a[81][81];bignumber f[81][81];int main(){    int n,m;cin>>n>>m;    for(int i=1;i<=n;i++)    {        for(int j=1;j<=m;j++)        {            cin>>a[i][j];        }    }    bignumber sum=0;    bignumber pow=2;    for(int k=1;k<=n;k++)    {        for(int i=1;i<=m;i++)f[i][i]=a[k][i]*pow;        for(int i=2;i<=m;i++)        {            for(int j=1;j<=m;j++)            {                int l=j,r=j+i-1;                if(r<=m)                {                    bignumber p=f[l+1][r]*pow+a[k][l]*pow;                    bignumber q=f[l][r-1]*pow+a[k][r]*pow;                    if(p>q)f[l][r]=p;                    else f[l][r]=q;                }            }        }        sum+=f[1][m];    }    cout<<sum;    return 0;}



0 0
原创粉丝点击