摘要

题目链接 难度等级 完成状态 完成分数 最后编辑时间 失误原因(初次提交分数)
矩阵取数游戏 ★☆☆☆☆ 答案正确 100 2014/11/15 20:50:25 没用高精度(40)

题意

n*m矩阵,每次取行首或尾的m个数字,每行取数的得分=被取走的元素值*2^i,求可以求出取数后的最大得分。

题解

贪心无效不解释。很容易发现每行之间没有关联,可以看做m组数据,DP的想法仍然是小推大,容易得到DP方程:

f[from][from+len-1]=max{
    (f[from][from+len-2]*2)+f[from+len-1][from+len-1],
    (f[from+1][from+len-1]*2)+f[from][from]
}

另外这题要用高精度。

代码

1166.cpp代码已折叠
展开折叠内容
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<cstdio>
#define NNN 1000000000
#define nnn 9
using namespace std;
class unsigned_huge_int
{
    public:
        const size_t size() const
        {
            return u.size();
        }
        friend const bool operator <(const unsigned_huge_int &a,const unsigned_huge_int &b)
        {
            if(a.size()==b.size())
            {
                for(int i=a.size()-1;i>=0;--i){
                    if(a.u[i]!=b.u[i])
                        return a.u[i]<b.u[i];
                }
                return 0;
            }
            return a.size()<b.size();
        }
        friend const bool operator ==(const unsigned_huge_int &a,const unsigned_huge_int &b)
        {
            if(a.size()==b.size())
            {
                for(int i=a.size()-1;i>=0;--i){
                    if(a.u[i]!=b.u[i])
                        return 0;
                }
                return 1;
            }
            return 0;
        }
        friend const bool operator <=(const unsigned_huge_int &a,const unsigned_huge_int &b)
        {
            return a<b || a==b;
        }
        friend const bool operator >(const unsigned_huge_int &a,const unsigned_huge_int &b)
        {
            return !(a<=b);
        }
        friend const bool operator >=(const unsigned_huge_int &a,const unsigned_huge_int &b)
        {
            return !(a<b);
        }
        friend const bool operator !=(const unsigned_huge_int &a,const unsigned_huge_int &b)
        {
            return a==b;
        }
        unsigned_huge_int()
        {
            u.clear();
            u.push_back(0);
        }
        unsigned_huge_int(const unsigned long long  &number)
        {
            u.clear();
            u.push_back(number);
            refresh();
        }
        unsigned_huge_int(const string&original)
        {
            u.clear();
            for(int i=original.size()-1,j=0,p=1;i>=0;--i)
            {
                j+=(original[i]-'0')*p;
                p*=10;
                if((!i) || p==NNN)
                {
                    u.push_back(j);
                    j=0;
                    p=1;
                }
            }
        }
        friend istream& operator >> (istream& os,unsigned_huge_int &ob)
        {
            string original;
            os>>original;
            ob=original;
            return os;
        }
        friend ostream& operator << (ostream& os,const unsigned_huge_int &ob)
        {
            os<<setw(0)<<setfill('0')<<ob.u[ob.size()-1];
            for(int i=ob.size()-2;i>=0;--i)
                os<<setw(nnn)<<setfill('0')<<ob.u[i];
            return os;
        }
        friend const unsigned_huge_int operator +(const unsigned_huge_int &a,const unsigned_huge_int &b)
        {
            unsigned_huge_int r;
            r.u.resize(max(a.size(),b.size()));
            for(int i=0;i<r.size();++i)
            {
                if(i<a.size())
                    r.u[i]+=a.u[i];
                if(i<b.size())
                    r.u[i]+=b.u[i];
            }
            r.refresh();
            return r;
        }
        const unsigned_huge_int d()
        {
            return *this+*this;
        }
        friend const unsigned_huge_int operator *(const unsigned_huge_int &a,const unsigned_huge_int &b)
        {
            if(b==2)
                return a+a;
            unsigned_huge_int r;
            r.u.resize(a.size()+b.size());
            for(int i=0;i<a.size();++i)
            {
                for(int j=0;j<b.size();++j)
                {
                    r.u[i+j]+=a.u[i]*b.u[j];
                }
            }
            r.refresh();
            return r;
        }
        friend const unsigned_huge_int operator -(const unsigned_huge_int &a,const unsigned_huge_int &b)
        {
            unsigned_huge_int r;
            const unsigned_huge_int *p1=&a,*p2=&b;
            if(*p1<*p2)
                swap(p1,p2);
            r.u.resize(p1->size());
            for(int i=0;i<r.size();++i)
                if(i<p2->size())
                    r.u[i]+=p1->u[i]-p2->u[i];
                else
                    r.u[i]+=p1->u[i];
            r.refresh();
            return r;
        }
    private:
        vector<unsigned long long> u;
        void refresh()
        {
            for(int i=0;i<size();++i)
            {
                if(u[i]>=NNN)
                {
                    if(i==size()-1)
                        u.push_back(u[i]/NNN);
                    else
                        u[i+1]+=u[i]/NNN;
                    u[i]%=NNN;
                }
                while(u[i]<0)
                {
                    u[i]+=NNN;
                    u[i+1]-=1;
                }
            }
            for(int i=size()-1;i!=0;--i)
            {
                if(u[i]==0&&size()!=1)
                {
                    u.pop_back();
                }
            }
        }
};
unsigned long long n,m;
unsigned_huge_int Ans=0,f[90][90];
int main()
{
    scanf("%llu%llu",&n,&m);
    for(int i=1;i<=n;++i)
    {
        for(int j=1;j<=m;++j)
        {
            unsigned long long A;
            scanf("%llu",&A);
            f[j][j]=A;
        }
        for(int len=2;len<=m;++len)
        {
            for(int from=1;from+len-1<=m;++from)
            {
                f[from][from+len-1]=std::max(
                    (f[from][from+len-2].d())+f[from+len-1][from+len-1],
                    (f[from+1][from+len-1].d())+f[from][from]
                );
            }
        }
        Ans=Ans+(f[1][m].d());
    }
    cout<<Ans;
}

著作权声明[编辑]

关于[编辑]