题目链接:传送门

题目大意:

给定长度为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. net core 上传并使用EPPlus导入Excel文件

    1.  cshtml页面 form <form id="form" method="post" action="/SaveValueBatch& ...

  2. samba服务断开某个用户 samba客户端断开自动登录

    结论: 方式二成功率更高,方式一有时候会失败. 方式一:windows命令行 删除链接 1. net use 查看连接情况 2. net use * /del 3. 如果不行 重启电脑 方式二: 删除 ...

  3. img2html实现将图片转换成网页

    简单介绍img2html的用法,安装就不用说了pip.这个包现只支持python2,支持python的话需改下源码这几个部分: 加注释的是修改的地方 #!/usr/bin/env python # e ...

  4. Python中os与sys模块的区别

    os与sys模块的官方解释如下: os: This module provides a portable way of using operating system dependent functio ...

  5. 《Python》常用模块之collections模块

    内置的数据类型: int  float  complex str  list  tuple dict  set 基础数据类型: int  float  complex str  list  tuple ...

  6. C/C++知识补充 (1)

    ● C++的圆括号运算符() 下列关于圆括号运算符的功能说法不正确的是(C) . A. 可用于强制类型转换 B 可用于类型构造 C 可用于类型声明 D 可用于函数调用 对大部分可重载的运算符来说,它既 ...

  7. zabbix安装部署(server部分)

    Linux下常用的系统监控软件有Nagios.Cacti.Zabbix.Monit等,这些开源的软件,可以帮助我们更好的管理机器,在第一时间内发现,并警告系统维护人员. 今天开始研究下Zabbix,使 ...

  8. Cracking The Coding Interview 1.5

    //原文: // // Write a method to replace all spaces in a string with '%20'. // #include <iostream> ...

  9. c++的读入txt文件(转)

    因为学姐的项目需要,要用到excel的读入读出,百度过后发现txt的读入读出比较简单,于是,我采用了先把excel转成txt,然后再读入. 方法是csdn上的天使的原地址:   https://blo ...

  10. L299 EST 科技英语翻译-美学取向 (下)

    4. Ordering(有序美) DescriptiveExpositoryArgumentative Chinese: end focus 句尾焦点English: beginning focus ...