今天来记录一个简单的DP题(我不是在水博客!)
1492: Problem D
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 312 Solved: 125
[Submit][Status][Web Board]
Description
Chieh最近在网上看到蓝翔非常火热。不知为什么他想到了一个问题,有一个n*m的矩阵
每一个小块里有k个石头。。现在挖掘机在左上角,挖掘机非常强大。。可以放无限的石头
但是它只能往右或者往下移动,现在Chieh想知道最多的石头从左上角到右下角。
Input
T 组数 T<=100
n m 1<=n. m<=1000
n行m个数 为石头数量 0<=s<=1000
Output
对于每组测试数据,输出对应的答案。
Sample Input
2
1 1
1
4 3
1 3 4
11 32 4
11 32 11
44 21 41
Sample Output
1
138
题目让我们找到挖掘机可挖掘的最大值,核心思想就是贪心算法,具体点就是DP背包问题
这道题目很显然是一个简单的DP题目,我们只需要找到动态转移方程即可,这里的动态转移方程为dp[i][j] = max(dp[i-1][j] , dp[i][j-1]) + a[i][j]。
以下为AC 代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1005;
typedef long long ll;
int a[maxn][maxn],dp[maxn][maxn];
int main(){
int n,m;
int T;
cin >> T;
while (T--) {
memset(dp, 0, sizeof dp);
memset(a, 0, sizeof a);
scanf("%d%d",&n,&m);
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin >> a[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
dp[i][j] = max(dp[i-1][j], dp[i][j-1])+a[i][j];
cout << dp[n][m] << endl;
}
}
return 0;
}
昨天经过高人指点,得到了一种更快的AC代码,而且还省空间,其实a数组的设置是没有必要的,以下是AC代码
#include<bits/stdc++.h>
using namespace std;
int dp[2][1005];
int main(){
int t,m,n,x,e;
cin >> t;
while(t--)
{
scanf("%d%d",&n,&m);
e = 0;
memset(dp, 0, sizeof dp);
for(int i=1;i<=n;i++)
{
e = 1- e;
for(int j=1;j<=m;j++){
cin >> x;
dp[e][j] = max(dp[1-e][j],dp[e][j-1]);
dp[e][j] += x;
}
}
cout << dp[e][m] << endl;
}
return 0;
}