题目链接:传送门

题目大意:

给定长度为m的数列aj,每次从两端取一个数,得到2k * aj的价值(k为当前的次数,从1开始到m),总共有n行这样的数列,求最大价值总和。

1 ≤ n, m ≤ 80, 0 ≤ aj ≤ 1000;

思路:

状态f[i][j]表示取剩下ai,ai+1,…,aj时的最大价值。

起始状态:

  f[0][m-1] = 0;

转移方程:

  f[i][j-1] = max(f[i][j-1], f[i][j] + 取掉aj得到的价值);

  f[i+1][j] = max(f[i+1][j], f[i][j] + 取掉ai得到的价值);

PS:吃灰模板居然出了bug,还因此WA了一发,是时候更新一下高精模板了。

#include <bits/stdc++.h>

using namespace std;
const int maxn = ;
const int MAX_N = + ; struct bigInt{
int len, d[maxn]; void clean() { while(len > && !d[len-]) len--; }
string str() const {
string s;
for (int i = ; i < len; i++) s += d[len--i] + '';
return s;
} bigInt() { memset(d, , sizeof d); len = ; }
bigInt(int num) { *this = num; }
bigInt(char* num) { *this = num; } bool operator < (const bigInt& b) const {
if(len != b.len)
return len < b.len;
for (int i = len-; i >= ; i--)
if (d[i] != b.d[i])
return d[i] < b.d[i];
return false;
}
bool operator >(const bigInt& b) const{return b < *this;}
bool operator<=(const bigInt& b) const{return !(b < *this);}
bool operator>=(const bigInt& b) const{return !(*this < b);}
bool operator!=(const bigInt& b) const{return b < *this || *this < b;}
bool operator==(const bigInt& b) const{return !(b < *this) && !(b > *this);} bigInt operator = (const char* num) {
memset(d, , sizeof d);
len = strlen(num);
for (int i = ; i < len; i++)
d[i] = num[len--i] - '';
clean();
return *this;
}
bigInt operator = (int num) {
char s[];
sprintf(s, "%d", num);
*this = s;
return *this;
}
bigInt operator + (const bigInt& b) {
bigInt c = *this;
for (int i = ; i < b.len; i++) {
c.d[i] += b.d[i];
c.d[i+] += c.d[i]/;
c.d[i] %= ;
}
c.len = max(len, b.len)+;
c.clean();
return c;
}
bigInt operator - (const bigInt& b) {
bigInt c = *this;
int i;
for (i = ; i < b.len; i++) {
c.d[i] -= b.d[i];
if (c.d[i] < ) c.d[i] += , c.d[i+]--;
}
while (c.d[i] < ) c.d[i++] += , c.d[i]--;
c.clean();
return c;
}//只能正数大减小
bigInt operator * (const bigInt& b) const {
bigInt c;
for (int i = ; i < len; i++)
for (int j = ; j < b.len; j++)
c.d[i+j] += d[i] * b.d[j];
for (int i = ; i < len+b.len || !c.d[i]; c.len = ++i) {
c.d[i+] += c.d[i] / ;
c.d[i] %= ;
}
c.clean();
return c;
}
bigInt operator / (const bigInt& b) {
bigInt c = *this, res = ;
for (int i = ; i < len; i++) {
res = res* + c.d[len--i];
int j;
for (j = ; j < ; j++)
if(res < b*(j+))
break;
c.d[len--i] = j;
res = res - b*j;
}
c.clean();
return c;
}
bigInt operator % (const bigInt& b) {
bigInt res = ;
for (int i = ; i < len; i++) {
res = res* + d[len--i];
int j;
for (j = ; j < ; j++)
if(res < b*(j+))
break;
res = res - b*j;
}
return res;
}
bigInt operator += (const bigInt& b) {
*this = *this + b;
return *this;
}
}; istream& operator >> (istream& in, bigInt& x)
{
string s;
in >> s;
x = s.c_str();
return in;
} ostream& operator << (ostream& out, const bigInt& x)
{
out << x.str();
return out;
} int N, M;
bigInt mat[MAX_N];
bigInt mul[MAX_N];
bigInt f[MAX_N][MAX_N]; bigInt dp()
{
bigInt cur;
for (int i = ; i < M; i++) {
for (int j = M-; j > i; j--) {
// cout << "f[" << i << "][" << j << "] = " << f[i][j] << ":" << endl;
// cout << "f[" << i << "][" << j-1 << "] = " << f[i][j-1] << ' ' << "f[" << i+1 << "][" << j << "] = " << f[i+1][j] << endl;
f[i][j-] = max(f[i][j-], f[i][j] + mul[M-(j-i+)+]*mat[j]);
f[i+][j] = max(f[i+][j], f[i][j] + mul[M-(j-i+)+]*mat[i]);
// cout << "f[" << i << "][" << j-1 << "] = " << f[i][j-1] << ' ' << "f[" << i+1 << "][" << j << "] = " << f[i+1][j] << endl;
}
}
for (int i = ; i < M; i++) {
cur = max(cur, f[i][i] + mul[M]*mat[i]);
}
// cout << cur << endl;
return cur;
} int main()
{
cin >> N >> M;
mul[] = ;
for (int i = ; i < MAX_N; i++)
mul[i] = mul[i-] * ;
bigInt ans;
while (N--) {
for (int i = ; i < M; i++) {
cin >> mat[i];
}
for (int i = ; i < M; i++)
for (int j = i; j < M; j++)
f[i][j] = ;
ans = ans + dp();
}
//模板居然出了bug,怕是在硬盘里吃灰吃多了
while (ans.d[ans.len-] > ) {
ans.d[ans.len] = ans.d[ans.len-] / ;
ans.d[ans.len-] %= ;
ans.len++;
}
cout << ans << endl;
return ;
}

P1005 矩阵取数游戏(动态规划+高精度)的更多相关文章

  1. 【Luogu】P1005矩阵取数游戏(高精度+DP)

    题目链接 yeah终于过辣! DP,f[i][j]表示每行还剩i到j这个区间的数没取的时候的值.借这个题我也把高精度的短板弥补了一下,以后高精加高精乘应该是没问题了. 哇终于不怂高精了…… 放上代码. ...

  2. [LuoguP1005]矩阵取数游戏 (DP+高精度)

    题面 传送门:https://www.luogu.org/problemnew/show/P1005 Solution 我们可以先考虑贪心 我们每一次都选左右两边尽可能小的数,方便大的放在后面 听起来 ...

  3. 洛谷P1005 矩阵取数游戏

    P1005 矩阵取数游戏 题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次 ...

  4. P1005 矩阵取数游戏 区间dp 高精度

    题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n \times mn×m的矩阵,矩阵中的每个元素a_{i,j}ai,j​均为非负整数.游戏规则如下: 每次取数时须从每行各取走一个元素,共n ...

  5. [NOIP2007] 提高组 洛谷P1005 矩阵取数游戏

    题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. ...

  6. 洛谷 P1005 矩阵取数游戏

    题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. ...

  7. P1005 矩阵取数游戏[区间dp]

    题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的\(m*n\)的矩阵,矩阵中的每个元素\(a_{i,j}\)均为非负整数.游戏规则如下: 每次取数时须从每行各取走一个元素,共n个.经过m次后 ...

  8. 洛谷 P1005 矩阵取数游戏 (区间dp+高精度)

    这道题大部分时间都在弄高精度-- 还是先讲讲dp吧 这道题是一个区间dp,不过我还是第一次遇到这种类型的区间dp f[i][j]表示取了数之后剩下i到j这个区间的最优值 注意这里是取了i之前和j之后的 ...

  9. P1005 矩阵取数游戏

    传送门 思路: △ 区间动规 对于每行,有 f [ i ][ j ] 代表取区间 [ i , j ] 的最大值. 然后转移方程我们考虑,对于每一个新的 f [ i ][ j ],有两种情况(下面定义  ...

随机推荐

  1. 窗体应用程序防腾讯QQ源码

    窗体应用程序防腾讯QQ源码 using System; using System.Collections.Generic; using System.ComponentModel; using Sys ...

  2. vs 编译库文件

    vs编译的库文件 静态库  debug和release版本 需要分开编译,我编译和实践的结果. 但是我也发现有的debug release都用同一个(搞不清楚). 然后添加到工程应用. 静态库  附件 ...

  3. 服务消费和负载(Feign)

    Spring Cloud Feign Spring Cloud Feign是一套基于Netflix Feign实现的声明式服务调用客户端.它使得编写Web服务客户端变得更加简单.我们只需要通过创建接口 ...

  4. C/S与B/S架构对比

    概述 在这个信息急剧膨胀的社会,我们不得不说人类正进入一个崭新的时代,那就是信息时代.信息时代的一个主要而显著的特征就是计算机网络的应用.计算机网络从最初的集中式计算,经过了Client/Server ...

  5. hdu3518

    题解: 后缀数组 枚举长度为k(1<=k<=len/2)的满足要求的子串个数 代码: #include<cstdio> #include<cmath> #inclu ...

  6. JavaScript -基础- 变量、常量

    一.变量 <script> var a=1 var b=3 var a= 1;   //使用var 定义变量,分号结尾(可不加,换行符也可) var b=3; var a= 1; var ...

  7. 7.6 C++基本序列式容器效率比较

    参考:http://www.weixueyuan.net/view/6403.html 总结: 对于vector而言,它只是一个可以伸缩长度的数组 对于deque而言,它是一个可以操作头部和尾部的并且 ...

  8. do while

    do while结构的基本原理和while结构是基本相同的,但是它保证循环体至少被执行一次.因为它是先执行代码,后判断条件,如果条件为真,继续循环.

  9. maven3.5.0在win10中的安装及环境变量配置

    1.maven的下载地址http://maven.apache.org/download.cgi.如下图,下载apache-maven-3.5.0-bin.zip 2.解压缩到自己指定的文件下,mav ...

  10. netty源码理解(二) serverstrap.bind()

    eventloop是一个线程,里面有一个executor封装了一个线程工厂,在启动的时候启动一个线程,传入的实现了runnable的内部类,里面调用了eventloop的run方法.