wikioi p1166 矩阵取数游戏
来源:互联网 发布:小型图书馆源码 编辑:程序博客网 时间:2024/04/24 18:48
这题是动规还好 问题是要加功能很齐全的高精度 一下子就变得恶心了
高精度没法说.....就不说了...
dp[i][j] 表示计算的那一层还剩下为 [ i , j ] 的区间 保存之前取数的最大值
首先因为每一层求得最值都互不影响
所以for( res 1->n)枚举每一层的最大值
然后for( k 1->m)枚举第几次取数 同时计算2的k次幂
最后枚举左区间( L 1->k) 因为第k次取数该排最多只能取k个 所以L枚举到k就行了
通过k和L可以计算出右区间端点 R = m + L - 1 - k ;
动规方程为dp[L][R] = max(dp[L - 1][R] + (2^k )* map[res][L - 1], dp[L][R + 1] + (2^k) * map[res][R + 1])
每一层取完数字的最大值就是之前计算的dp[i][j]中的一个最大值 ans = max(dp[i][j] , ans)
再吧ans累加即可得到答案
一开始看错题目了,以为是总共取M次,谁知道是每次M次,那这题就简单了,没的说。
但是高精度有点烦。
现在终于自己写出来了
/*Sour : NOIPSenior ID : ThaddeusPID : 1005*/#include<stdio.h>#include<iostream>#include<algorithm>#include<memory.h>using namespace std;const int maxn = 81;const int maxm = 5;const long long radix = 1000000000;long long a[maxn][maxn][maxm];long long f[maxn][maxn][maxn][maxm]; //第i行头取j~k的最大值 long long r[maxn][maxm]; //二进制数 long long ans[maxm];long long mul1[maxm];long long mul2[maxm];long long com1[maxm];long long com2[maxm];long long zero[maxm];long long two[maxm];long long temp[maxm];int n,m;void init(){int i,j;scanf("%d %d",&n,&m);for (i=1;i<=n;i++)for (j=1;j<=m;j++)scanf("%lld",&a[i][j][1]);}bool comp(long long x[],long long y[]) //判断数字x是否比y大,如果是,返回true {int i;for (i=maxm-1;i>=1;i--){if (x[i]>y[i]) return true;if (x[i]<y[i]) return false;}return true;}void plu(long long x[],long long y[],long long z[]) //将x与y相加的值记录到z中{int i;for (i=0;i<maxm;i++)z[i]=0;for (i=1;i<maxm;i++){z[i]+=x[i]+y[i];z[i+1]+=z[i]/radix;z[i]%=radix;}for (i=1;i<maxm;i++)z[i]+=z[i-1]/radix,z[i-1]%=radix;} void mult(long long x[],long long y[],long long z[])//将x与y相乘的值记录到z中{int i,j;for (i=0;i<maxm;i++)z[i]=0;for (i=1;i<maxm;i++)for (j=1;j<maxm;j++)if (i+j<=maxm){z[i+j-1]+=x[i]*y[j];z[i+j]+=z[i+j-1]/radix;z[i+j-1]%=radix;}for (i=0;i<maxm;i++){z[i+1]+=z[i]/radix;z[i]%=radix;}}void _put(long long x[]){int i;i = maxm-1;while(!x[i]&&i>1) --i;printf("%lld",x[i--]);for (;i>=1;i--)printf("%09lld",x[i]);}void _init(){int i;memset(ans,0,sizeof(ans));memset(f,0,sizeof(f));memset(zero,0,sizeof(zero));memset(two,0,sizeof(two)); memset(r,0,sizeof(r));two[1]=2;r[0][1]=1;for (i=1;i<=m;i++)mult(r[i-1],two,r[i]);}void work(){int i,j,k,p;for (i=1;i<=n;i++){for (j=1;j<=m;j++)mult(a[i][j],r[m],f[i][j][j]);for (p=1;p<=m;p++)for (j=1;j+p<=m;j++){k = p+j;mult(a[i][j],r[m-p],mul1);mult(a[i][k],r[m-p],mul2);plu(mul1,f[i][j+1][k],com1);plu(mul2,f[i][j][k-1],com2);if (comp(com1,com2))plu(com1,zero,f[i][j][k]);elseplu(com2,zero,f[i][j][k]);}}}void put(){int i;for (i=1;i<=n;i++)plu(ans,f[i][1][m],temp),plu(temp,zero,ans);_put(ans);}int main(){freopen("test.in","r",stdin);freopen("test.out","w",stdout);init();_init();work();put();return 0;}
- wikioi p1166 矩阵取数游戏
- Wikioi P1166 矩阵取数游戏
- wikioi 1166 矩阵取数游戏
- 【wikioi】1166矩阵取数游戏
- wikioi 1166 矩阵取数游戏
- wikioi 1037 取数游戏
- [Wikioi 1037]取数游戏
- wikioi 1166 矩阵取数游戏(2007年NOIP全国联赛提高组)
- wikioi-天梯-普及一等-区间dp-1166:矩阵取数游戏
- 矩阵取数游戏
- 矩阵取数游戏
- 矩阵取数游戏
- 矩阵取数游戏
- 矩阵取数游戏
- codevs1166 矩阵取数游戏
- Codevs1166 矩阵取数游戏
- NOIP2007 矩阵取数游戏
- P1378 矩阵取数游戏
- HDU_4701_Game
- 实现FusionChart动态获取数据(二)
- 关系模型的基本概念
- N个筛子,掷出M值的可能性
- 2013.8.25
- wikioi p1166 矩阵取数游戏
- 烟台大学acm暑期集训总结
- 谷歌笔试题-背包问题
- POJ 1637 - Sightseeing tour 判断混合图是否是欧拉回路(最大流)
- Hibernate 4 Util
- 重载_static_new
- wikioi p1010 过河卒
- vi、akw和sed总结
- 原来NSArray装的也是强类型元素,一直以为是弱类型.