思路:将初始化的价值都增加1,因为迷宫中宝物的价值可能为0,要用long来存储数据,不然中间会造成溢出
AC代码:
import java.util.Scanner; public class Main { static long[][][][] visit = new long[60][60][15][15]; static int[][] map = new int[60][60]; static int[][] dir = {{0,1},{1,0}}; static int n,m,k; public static void main(String[] args) { Scanner in = new Scanner(System.in); //每一维度记录一个值,坐标x和y,携带的数量以及携带的最重的重量 n = in.nextInt(); m = in.nextInt(); k = in.nextInt(); for (int i=0; i<60; i++) { for (int j=0; j<60; j++) { for (int k=0; k<15; k++) { for (int l=0; l<15; l++) { visit[i][j][k][l] = -1; } } } } //因为宝物的价值有可能为0,不好控制,所以将初值都加1 for (int i=0; i<n; i++) { for (int j=0; j<m; j++) { map[i][j] = in.nextInt() + 1; } } long sum = dfs(0,0,0,0); System.out.println(sum); } private static long dfs(int x, int y, int f, int l) { if (visit[x][y][f][l] != -1) return visit[x][y][f][l]; if (x == n-1 && y == m-1) { //这条路径可行,返回1 if (f == k) { return visit[x][y][f][l] = 1; } else if (f == k-1 && map[x][y] > l) { return visit[x][y][f][l] = 1; } else { return visit[x][y][f][l] = 0; } } long sum = 0; for (int i=0; i<2; i++) { int newx = x + dir[i][0]; int newy = y + dir[i][1]; if (newx >= n || newy >= m) continue; if (map[x][y] > l && f + 1 <= k) { sum += dfs(newx,newy,f+1,map[x][y]) % 1000000007; } sum += dfs(newx,newy,f,l) % 1000000007; } return visit[x][y][f][l] = sum % 1000000007; } }
思路:参考的大神的代码,加了一点注释,地址:http://blog.csdn.net/rodestillfaraway/article/details/50529814
AC代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <queue> #include <stack> #include <map> #include <cstring> #include <climits> #include <cmath> #include <cctype> typedef long long ll; using namespace std; const int mod = 1000000007; int dp[55][55][15][15];//前2个是坐标,第三个是目前取到的件数,第四个是目前的最大值 int map1[55][55]; int main() { int n,m,k; while(scanf("%d%d%d",&n,&m,&k) != EOF) { int max = 0; for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) { scanf("%d",&map1[i][j]); map1[i][j]++;//在这加1,是因为物品的价值有可能为0,所有物品价值数加1,不影响最后的结果 if(map1[i][j] > max) { max = map1[i][j]; } } } memset(dp,0,sizeof(dp)); dp[1][1][0][0] = 1; dp[1][1][1][map1[1][1]] = 1; for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) { //在这一个点不取,.总件数为0 dp[i][j][0][0] += dp[i-1][j][0][0] + dp[i][j-1][0][0];//注意是加等 dp[i][j][0][0] %= mod; for(int p=1; p<=k; p++) { //在这一点不取,总件数为p for(int val = 0; val <= max; val++) { dp[i][j][p][val] += dp[i-1][j][p][val]; dp[i][j][p][val] %= mod; dp[i][j][p][val] += dp[i][j-1][p][val]; dp[i][j][p][val] %= mod; } //到目前为止,只取1件,且目前的这一点取 if(p == 1) { dp[i][j][1][map1[i][j]] += dp[i-1][j][0][0]; dp[i][j][1][map1[i][j]] %= mod; dp[i][j][1][map1[i][j]] += dp[i][j-1][0][0]; dp[i][j][1][map1[i][j]] %= mod; } //到目前为止,只取p件,且目前的这一点取 else { for(int val = 0; val < map1[i][j]; val++) { dp[i][j][p][map1[i][j]] += dp[i-1][j][p-1][val]; dp[i][j][p][map1[i][j]] %= mod; dp[i][j][p][map1[i][j]] += dp[i][j-1][p-1][val]; dp[i][j][p][map1[i][j]] %= mod; } } } } } int sum = 0; for(int i=0; i<=max; i++) { sum += dp[n][m][k][i]; sum %= mod; } printf("%d\n",sum); } return 0; }