2007OI, 矩阵取数游戏( 区间DP )

来源:互联网 发布:php 异步请求网页 编辑:程序博客网 时间:2024/06/04 20:04
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//BigIntegerint 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);                }        }}

原创粉丝点击