Problem Description:
帅帅经常跟同学玩一个矩阵取数游戏,对于一个给定的n*m的矩阵,矩阵中每个元素Aij为非负整数。游戏规则如下:
1.每次取数时须从每行各去走一个元素,共N个.M次后取完矩阵所有元素;
2.每次取数都是一个得分值,为每行取数的得分之和,每行取数的得分=被取走的元素值*2(2
右上角有个i),其中i表示第i次取数(从1开始编号)
3.每次取走的各个元素只能是该原素所在行的行首或行尾.
4.游戏结束总得分为M次取数得分之和
dp[i][j][k]表示当前行的在【i,j】区间内去k个数所取得的最大值
dp[i][j][k] = max(dp[i+1][j][k-1], dp[i][j-1][k-1])
ans = sum{dp[1][col][col]}.
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAXN 100
//BigInteger
int row, col;
int dp[MAXN][MAXN][MAXN], val[MAXN][MAXN];
int dfs(int row_idx, int start, int final, int cnt)
{
int left_rst, right_rst, base(1<<(col-cnt+1));
if( start == final ) {
return base*val[row_idx][start];
}
if( -1 != dp[start][final][cnt] ) {
return dp[start][final][cnt];
}
left_rst = val[row_idx][start]*base+dfs(row_idx, start+1, final, cnt-1);
right_rst = val[row_idx][final]*base+dfs(row_idx, start, final-1, cnt-1);
return dp[start][final][cnt] = max(left_rst, right_rst);
}
int main(int argc, char const *argv[])
{
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
#endif
int rst;
while( ~scanf("%d %d", &row, &col) ) {
for(int i = 1; i <= row; i ++) {
for(int j = 1; j <= col; j ++) {
scanf("%d", &val[i][j]);
}
}
rst = 0;
for(int i = 1; i <= row; i ++) {
memset(dp, -1, sizeof(dp));
rst += dfs(i, 1, col, col);
}
printf("%d\n", rst);
}
return 0;
}
这一个只能做对60%的测试数据,要Accepted 需要使用高精度
import java.io.*;
import java.util.*;
import java.math.*;
public class Main {
static int col;
static int MAXSIZE = 81;
static int[][] val = null;
static BigInteger[][][] dp = null;
public static BigInteger dfs(int row_idx, int s, int f, int cnt) {
BigInteger left_rst, right_rst, base;
base = BigInteger.valueOf(1);
for(int i = 0; i < (col-cnt+1); i ++) {
base = base.multiply(BigInteger.valueOf(2));
}
if( s == f ) {
return base.multiply(BigInteger.valueOf(val[row_idx][s]));
}
if( 0 != dp[s][f][cnt].compareTo(BigInteger.valueOf(-1)) ) {
return dp[s][f][cnt];
}
left_rst = base.multiply(BigInteger.valueOf(val[row_idx][s]));
left_rst = left_rst.add(dfs(row_idx, s+1, f, cnt-1));
right_rst = base.multiply(BigInteger.valueOf(val[row_idx][f]));
right_rst = right_rst.add(dfs(row_idx, s, f-1, cnt-1));
return dp[s][f][cnt] = left_rst.max(right_rst);
}
public static void main(String args[]) {
int row, init = -1;
BigInteger rst;
val = new int[MAXSIZE][MAXSIZE];
dp = new BigInteger[MAXSIZE][MAXSIZE][MAXSIZE];
Scanner cin = new Scanner(System.in);
while( cin.hasNext() ) {
row = cin.nextInt(); col = cin.nextInt(); rst = BigInteger.valueOf(0);
for(int i = 1; i <= row; i ++) {
for(int j = 1; j <= col; j ++) {
val[i][j] = cin.nextInt();
}
}
for(int i = 1; i <= row; i ++) {
for(int j = 0; j <= col; j ++) {
for(int k = 0; k <= col; k ++) {
for(int z = 0; z <= col; z ++) {
dp[j][k][z] = BigInteger.valueOf(-1);
}
}
}
rst = rst.add(dfs(i, 1, col, col));
}
System.out.println(rst);
}
}
}
2007OI, 矩阵取数游戏( 区间DP )
最新推荐文章于 2021-03-02 03:26:34 发布