题目链接:传送门

题目大意:

给定长度为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. jQuery获取select值

    jQuery操作select标签 即控制select的option属性 <select id="sid" > <option value="-1&quo ...

  2. xubuntu无法进图形界面问题

    http://www.ubuntugeek.com/fix-for-cant-login-after-upgrading-from-ubuntu-13-04-to-ubuntu-13-10.html ...

  3. ubuntu ssh前后台切换命令相关

    后台运行:命令+& 例如 sleep 60 & jobs -l 显示job的pid和状态 ps 显示用户进程 将第一个job切换回前台:fg 1 放到后台:bg 1 cltr + z ...

  4. 补交第二周作业:学习ka li

    在老师给的虚拟机上安装,试了n次都没有安装成功,百度上的说法也是众说纷纭. 之后重新安装了另一个版本的虚拟机,按照教程成功装上了ka li. 一. 安装VMtools:是为了方便宿主机与虚拟机间的文件 ...

  5. shell 键盘输入

    命令:read 从键盘读入数据,赋值变量 [root@ssgao shell]# cat b.sh #!bin/bash read a b c echo "a is : ${a}" ...

  6. 普通程序员,三年成为年薪70w架构师,只因做到了这些

    每个程序员.或者说每个工作者都应该有自己的职业规划,如果你不是富二代,不是官二代,也没有职业规划,希望你可以思考一下自己的将来.今天给大家分享的是一篇来自阿里Java架构师对普通程序员的职业建议,希望 ...

  7. go中for循环使用多个变量避坑

    go for循环语法为: for expression1, expression2, expression3 { // ... } 使用多个变量时,使用平行赋值,需要留意的是expression3处的 ...

  8. tomcat 服务器线程问题

    http://blog.csdn.net/wtopps/article/details/71339295 http://blog.csdn.net/wtopps/article/details/713 ...

  9. sass 变量的声明 嵌套

    sass 的默认变量一般是用来设置默认值,然后根据需求来覆盖的,覆盖的方式也很简单,只需要在默认变量之前重新声明下变量即可. $baseLineHeight: 2; $baseLineHeight: ...

  10. 一次Web请求返回406原因与解决方案

    ajax请求,响应信息返回的却是报错406,. 1.断点调试,进入对应处理方法,且得到正确信息返回到解析器.使用的是ssm,前端ftl 2.js将返回错误信息打出来,类似为: 百度406错误出现的原因 ...