取数游戏
来源:互联网 发布:网络歌手受排挤 编辑:程序博客网 时间:2024/05/02 00:19
时间限制:1秒 内存限制:64M
【问题描述】
帅帅经常跟同学玩一个取数游戏:对于一个给定的长度为n的整数序列,每个元素a[i]为非负整数。游戏规则如下:
1、每次取数时须从取走一个元素,共取n次;
2、每次取走的元素只能是当前序列的首或尾元素;
3、每次取数都有一个得分值,取数的得分=被取走的元素值*2^i,其中i表示第i次取数(从1开始编号);
4、游戏结束总得分为n次取数得分之和。
帅帅想请你帮忙写一个程序,对于任意矩阵,可以求出取数后的最大得分。
【输入格式】
第一行一个整数n,表示整数序列的长度。
第二行有n个用空格分开的非负整数,表示整数序列
【输出格式】
一个整数,表示最大得分。
【输入样例】
4
4 5 0 5
【输出样例】
122
【数据范围】
n<=20
0<=a[i]<=1000
这道题是一道区间动规
按照顺序处理这道题十分困难,反正我是没做出来。正方向难,我们就反着来;
反着来,我们就从最后一个元素倒着取,然后取倒数第二个,然后倒数第三个。。。。
一道区间动规题,我们就可以设状态转移方程为f(i,j)表示第i个数到第j个数的能取出的最大值;
现在假如我们还剩下两个数没取,我们可以先取前面那个数,然后再取后面那个数;我们也可以先取后面那个数,再取前面那个数;
那么,状态转移方程就出来了 f(i,j)=MAX{ f(i+1,j)+取a[i]的值 , f(i,j-1)+取a[j]的值 }
关于取a[i]的值该怎么计算呢?现在我们计算的是区间[i,j]的值,那么区间[i,j]中有j-i+1个元素,那么已经取走了N-j+i-1个元素,所以说
a[i]就是第N-j+i个元素,那么取走a[i]的值就是a[i]*2^(N-j+i)
所以状态转移方程最后就写为 f(i,j)=MAX{ f(i+1,j)+a[i]*2^(N-j+i) , f(i,j-1)+a[j]*2^(N-j+i) }
边界:f(i,i)=a[i]*2^N;
最后答案:f(1,N);
易错点:这道题,不能按照顺序扫描i,j,而是要按照区间大小从小到大扫描,即区间长度为2的先扫,然后区间长度为3的,然后为4的。。。。仔细想想为什么
程序:
#include<iostream>#include<cstdio>#include<cstring>using namespace std;int N;int a[25];long long d[30][30];long long mi(int x){ long long ans=1; for(int i=1;i<=x;i++) ans*=2; return ans;}void Ready(){ scanf("%d",&N); for(int i=1;i<=N;i++) scanf("%d",&a[i]); memset(d,0,sizeof(d)); for(int i=1;i<=N;i++) d[i][i]=a[i]*mi(N);}int MAX(int x,int y){ return x>y ? x:y;}void Working(){ for(int i=1;i<N;i++) for(int j=1;j<=N && i+j<=N;j++) { d[j][i+j]=MAX(d[j+1][i+j]+a[j]*mi(N-i),d[j][i+j-1]+a[i+j]*mi(N-i)); } cout<<d[1][N];}int main(){ Ready(); Working(); return 0;}
by:重庆一中吴松隐
- 取数游戏
- 矩阵取数游戏
- 取数游戏
- 取数游戏
- 矩阵取数游戏
- 蓝桥杯-取数游戏
- 取数游戏 贪心
- 取数游戏
- 1308 取数游戏
- 取数游戏:
- 矩阵取数游戏
- 取数游戏
- 矩阵取数游戏
- 取数游戏
- 【u108】取数游戏
- 9265:取数游戏
- 取数游戏
- 取数游戏
- sql convert 和 cast
- 怎样转换PDF格式文件
- myeclipse突然运行不了的原因以及解决方案
- nyoj103 A+B ProblemII
- jquery事件
- 取数游戏
- python object和type
- Enumeration和Iterator的区别
- ASP.Net中四位数字验证码的实现
- 启动Eclipse,不让m2e自动Updating index的解决办法
- *运项目1.0
- thinkphp模板输出cookie,session中的值
- 分数累加
- 第九周项目三输出星号图1