【b703】矩阵取数游戏
来源:互联网 发布:软件服务器加防御 编辑:程序博客网 时间:2024/06/06 07:39
Time Limit: 1 second
Memory Limit: 50 MB
【问题描述】
帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数。游戏规则如下:1. 每次取数时须从每行各取走一个元素,共n个。m次后取完矩阵所有的元素;2. 每次取走的各个元素只能是该元素所在行的行首或行尾;3. 每次取数都有一个得分值,为每行取数的得分之和;每行取数的得分 = 被取走的元素值*2i,其中i表示第i次取数(从1开始编号);4. 游戏结束总得分为m次取数得分之和。帅帅想请你帮忙写一个程序,对于任意矩阵,可以求出取数后的最大得分。
【输入】
包括n+1行;第一行为两个用空格隔开的整数n和m。第2~n+1行为n*m矩阵,其中每行有m个用单个空格隔开
【输出】
仅包含1行,为一个整数,即输入矩阵取数后的最大的分。
【输入样例1】
2 31 2 33 4 2
【输出样例1】
82
【输入输出样例1解释】
第1次:第一行取行首元素,第二行取行尾元素,本次的氛围1*21+2*21=6第2次:两行均取行首元素,本次得分为2*22+3*22=20第3次:得分为3*23+4*23=56。总得分为6+20+56=82
【输入样例2】
1 44 5 0 5
【输出样例2】
122
【输入样例3】
2 1096 56 54 46 86 12 23 88 80 4316 95 18 29 30 53 88 83 64 67
【输出样例3】
316994
【 限制】
60%的数据满足:1<=n, m<=30,答案不超过1016100%的数据满足:1<=n, m<=80,0<=aij<=1000
【题目链接】:http://noi.qz5z.com/viewtask.asp?id=b703
【题意】
中文题
【题解】
这道题可以分成n个步骤;
即每一行与每一行之间是独立的;
所以我们可以一行一行地进行处理;
设
f[i][j]表示取当前行区间[i..j]内的数能够获得的最大值;
则
f[i][j] = 2*max(a[i]+f[i+1][j],f[i][j-1]+a[j]);
这里的2对外层的区间乘的次数比较少,对内层的区间里的数乘得比较多;
且从内到外是递增1的;
正符合题目的要求;
写一个记忆化搜索就好了;
因为数据比较大;
要写一个高精度;
。。。
挺麻烦的。
(一开始那个a数组没有init调了很久。。做高精度加法的时候要注意啊,不然之前的数据会保留下来的。。)
【完整代码】
#include <cstdio>#include <algorithm>#include <cmath>using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define LL long long#define rep1(i,a,b) for (int i = a;i <= b;i++)#define rep2(i,a,b) for (int i = a;i >= b;i--)#define mp make_pair#define pb push_back#define fi first#define se second#define rei(x) scanf("%d",&x)#define rel(x) scanf("%I64d",&x)typedef pair<int,int> pii;typedef pair<LL,LL> pll;const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};const double pi = acos(-1.0);const int MAXM = 110;struct bignum{ int a[110],len; void init() { rep1(i,1,100) a[i] = 0; }};int n,m;bignum f[MAXM][MAXM],emp,a[MAXM],ans;bignum plu(bignum a,bignum b){ bignum c; rep1(i,1,100) c.a[i] = 0; c.len = max(a.len,b.len); int x = 0; rep1(i,1,c.len) { c.a[i] = c.a[i] + a.a[i]+b.a[i] + x; x = c.a[i]/10; c.a[i] %= 10; } while (x>0) { c.a[++c.len] = x; x = c.a[c.len]/10; c.a[c.len]%=10; } return c;}bignum ma(bignum a,bignum b){ int len1 = a.len,len2 = b.len; if (len1>len2) return a; else if (len1<len2) return b; rep2(i,len1,1) if (a.a[i]!=b.a[i]) { if (a.a[i]>b.a[i]) return a; else return b; } return a;}bignum dfs(int l,int r){ if (l>r) return emp; if (f[l][r].a[1]!=-1) return f[l][r]; if (l==r) return plu(a[l],a[l]); //f[l][r] = 2*max(a[l]+dfs(l+1,r),dfs(l,r-1)+a[r]); bignum temp1 = plu(a[l],dfs(l+1,r)); bignum temp2 = plu(dfs(l,r-1),a[r]); bignum temp3 = ma(temp1,temp2); return f[l][r] = plu(temp3,temp3);}int main(){ //freopen("F:\\rush.txt","r",stdin); ans.len = 1;ans.a[1] =0;ans.init(); emp.a[1] = 0,emp.len = 1; emp.init(); rei(n);rei(m); rep1(i,1,n) { rep1(ii,1,m) rep1(jj,1,m) { f[ii][jj].init(); f[ii][jj].len = 1; f[ii][jj].a[1] = -1; } rep1(j,1,m) { int temp,len=0; rei(temp); a[j].init(); while (temp>0) { a[j].a[++len] = temp%10; temp/=10; } if (len==0) { a[j].a[1] = 0; a[j].len = 1; } else a[j].len = len; } ans=plu(ans,dfs(1,m)); } rep2(i,ans.len,1) printf("%d",ans.a[i]); return 0;}
0 0
- 【b703】矩阵取数游戏
- 矩阵取数游戏
- 矩阵取数游戏
- 矩阵取数游戏
- 矩阵取数游戏
- 矩阵取数游戏
- codevs1166 矩阵取数游戏
- Codevs1166 矩阵取数游戏
- NOIP2007 矩阵取数游戏
- P1378 矩阵取数游戏
- P1005 矩阵取数游戏
- P1005 矩阵取数游戏
- NOIP2007【矩阵取数游戏】
- codevs1166矩阵取数游戏
- NOIP2007矩阵取数游戏
- 【NOIP2007】矩阵取数游戏
- P1005 矩阵取数游戏
- 【矩阵取数游戏】解题报告
- 抽取的html文件有些空格字符无法去除
- JSP自定义EL函数
- 对程序设计初学者谈程序的效率
- Linux Signal 信号量的使用
- 单链表翻转(递归与非递归)
- 【b703】矩阵取数游戏
- Android UI 显示工具——HierarchyViewer工具
- 微信开发者工具的快捷键
- Spring Bean生命周期
- httpclient详解
- RCC_Configuration()有什么用?
- java基础七预定义类
- Linux(CentOS)环境下安装MySQL
- JQuery选择器案例