poj 2948 Martian Mining dp
2013-04-14 19:39
309 查看
喜欢这样的题目
有一些思考的地方
关键是注意到一个地方
往左运,往上运的点都是连续的(原因自己想想就明白了)
否则不是最优的
有了这一点就可以dp了
dp[i][j]表示第i行,第一个向上的点是j时的最优解。
状态转移
for(int
k=j;k<=n+1;k++)
dp[i+1][k]=max(dp[i+1][k],dp[i][j]+sum1[i+1][k-1]+sum2[i+1][k]);
sum1,sum2表示两种矿连续的一段和
还有一点需要说明的,复杂度500*500*500超过一亿了,为什么可以过,第一常数很小,因为只进行一次运算和比较。第二k是从j开始循环的。所以实际的运算次数要比这个小得多。
#include
#include
#include
using namespace std;
const int maxn=555;
int dp[maxn][maxn],sum1[maxn][maxn],sum2[maxn][maxn];
int max(int a,int b)
{
if(a>b)
return(a);
return(b);
}
int main()
{
int n,m;
while(scanf("%d
%d",&n,&m),n&&m)
{
memset(dp,0,sizeof(dp));
memset(sum1,0,sizeof(sum1));
memset(sum2,0,sizeof(sum2));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%d",&sum1[i][j]);
sum1[i][j]+=sum1[i][j-1];
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&sum2[i][j]);
//
printf("hi");
for(int i=1;i<=n;i++)
for(int j=m;j>=1;j--)
sum2[i][j]+=sum2[i][j+1];
for(int i=0;i
for(int j=1;j<=n+1;j++)
{
for(int
k=j;k<=n+1;k++)
dp[i+1][k]=max(dp[i+1][k],dp[i][j]+sum1[i+1][k-1]+sum2[i+1][k]);
}
int ans=0;
for(int i=1;i<=n+1;i++)
ans=max(dp
[i],ans);
printf("%d\n",ans);
}
return 0;
}
有一些思考的地方
关键是注意到一个地方
往左运,往上运的点都是连续的(原因自己想想就明白了)
否则不是最优的
有了这一点就可以dp了
dp[i][j]表示第i行,第一个向上的点是j时的最优解。
状态转移
for(int
k=j;k<=n+1;k++)
dp[i+1][k]=max(dp[i+1][k],dp[i][j]+sum1[i+1][k-1]+sum2[i+1][k]);
sum1,sum2表示两种矿连续的一段和
还有一点需要说明的,复杂度500*500*500超过一亿了,为什么可以过,第一常数很小,因为只进行一次运算和比较。第二k是从j开始循环的。所以实际的运算次数要比这个小得多。
#include
#include
#include
using namespace std;
const int maxn=555;
int dp[maxn][maxn],sum1[maxn][maxn],sum2[maxn][maxn];
int max(int a,int b)
{
if(a>b)
return(a);
return(b);
}
int main()
{
int n,m;
while(scanf("%d
%d",&n,&m),n&&m)
{
memset(dp,0,sizeof(dp));
memset(sum1,0,sizeof(sum1));
memset(sum2,0,sizeof(sum2));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%d",&sum1[i][j]);
sum1[i][j]+=sum1[i][j-1];
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&sum2[i][j]);
//
printf("hi");
for(int i=1;i<=n;i++)
for(int j=m;j>=1;j--)
sum2[i][j]+=sum2[i][j+1];
for(int i=0;i
for(int j=1;j<=n+1;j++)
{
for(int
k=j;k<=n+1;k++)
dp[i+1][k]=max(dp[i+1][k],dp[i][j]+sum1[i+1][k-1]+sum2[i+1][k]);
}
int ans=0;
for(int i=1;i<=n+1;i++)
ans=max(dp
[i],ans);
printf("%d\n",ans);
}
return 0;
}
相关文章推荐
- poj&nbsp;3267&nbsp;The&nbsp;Cow&nbsp;Lexicon(DP)
- poj&nbsp;2250&nbsp;Compromise(DP)
- ACM: DP训练好题 动态规划题 poj 1…
- poj&nbsp;2096&nbsp;Collecting&nbsp;Bugs&nbsp;期望dp
- poj&nbsp;1159&nbsp;Palindrome(DP&nbsp;空间压缩…
- poj&nbsp;1609&nbsp;Tiling&nbsp;Up&nbsp;Blocks(DP)
- ACM: 动态规划题 poj 2057 树状DP
- poj&nbsp;3249&nbsp;Test&nbsp;for&nbsp;Job&nbsp;dp(动态规…
- poj&nbsp;1191&nbsp;棋盘分割&nbsp;dp
- poj&nbsp;1159&nbsp;Palindrome(DP)
- poj&nbsp;3661&nbsp;Running&nbsp;dp(动态规划)
- poj&nbsp;2486&nbsp;Apple&nbsp;Tree&nbsp;tree&nbsp;dp
- poj&nbsp;1155&nbsp;TELE&nbsp;树形dp
- POj 1159 Palindrome (dp)
- poj&nbsp;3181&nbsp;Dollar&nbsp;Dayz&nbsp;dp(动态规划…
- poj&nbsp;1952&nbsp;BUY&nbsp;LOW,&nbsp;BUY&nbsp;LOWER&nbsp;dp
- ACM: 图论题+记忆DP poj 2662 (边…
- ACM: DP+floyd 动态规划题 poj 117…
- ACM: 动态规划题 poj 1192 树形DP
- poj&nbsp;3280&nbsp;Cheapest&nbsp;Palindrome&nbsp;dp(…