hdu2845 dp

这题开始的思路:用二维数组来存,果断超时了,因为数组开不了。

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define maxn 10002
int map[maxn][maxn],dp[maxn][maxn],ans[maxn];
int main()
{
    int i,j;
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                scanf("%d",&map[i][j]);
            }
        }
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                dp[i][j]=max(dp[i][j-1],dp[i][j-2]+map[i][j]);
            }
        }
        /*for(i=1;i<=n;i++)
            printf("%d ",dp[i][m]);
        puts("");*/
        for(i=1;i<=n;i++)
            ans[i]=0;
        for(i=1;i<=n;i++)
        {
            if(i==1)
            {
                ans[i]=max(ans[i],dp[i][m]);
            }
            else
            {
                ans[i]=max(ans[i-1],ans[i-2]+dp[i][m]);
            }
        }
        printf("%d\n",ans[n]);
    }
}

后来看了别人的题解,使用一维数组来存。

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define maxn 200010
int dp[maxn],ans[maxn],map[maxn];
int max(int x,int y)
{
    return x>y?x:y;
}
int main()
{
    int i,j;
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(dp,0,sizeof(dp));
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                scanf("%d",&dp[j]);
            }
            for(j=1;j<=m;j++)
            {
                dp[j]=max(dp[j-1],dp[j-2]+dp[j]);
            }
            ans[i]=dp[m];
        }
        /*for(i=1;i<=n;i++)
            printf("%d ",dp[i][m]);
        puts("");*/
        for(i=2;i<=n;i++)
        {
            ans[i]=max(ans[i-2]+ans[i],ans[i-1]);
        }
        printf("%d\n",ans[n]);
    }
}
时间: 2024-11-09 11:36:51

hdu2845 dp的相关文章

hdu2845(dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2845 题意:给你一个n*m的矩阵,每个位置有一定数量的豆子,如果你去map[x][y]位置上的豆子,则map[i-1][]行和map[i+1][]行,以及map[i][j-1]和map[i][j+1]位置上的豆子都不能再取. 分析:水dp,先算出每行的最大值,在对n行的最大值dp得结果.dp[i][1]表示前i个且取了第i个达到的最大值,dp[i][0]表示前i个且不取第i个达到的最大值. 状态转移

DP总结 ——QPH

常见优化 单调队列 形式 dp[i]=min{f(k)} dp[i]=max{f(k)} 要求 f(k)是关于k的函数 k的范围和i有关 转移方法 维护一个单调递增(减)的队列,可以在两头弹出元素,一头压入元素. 队列中维护的是两个值.一个是位置,这和k的范围有关系,另外一个是f(k)的值,这个用来维护单调性,当然如果f(k)的值可以利用dp值在O(1)的时间内计算出来的话队列中可以只维护一个表示位置的变量. 枚举到一个i的时候,首先判断队首元素的位置是否已经不满足k的范围了,如果不满足就将队首

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

POJ - 3186 Treats for the Cows (区间DP)

题目链接:http://poj.org/problem?id=3186 题意:给定一组序列,取n次,每次可以取序列最前面的数或最后面的数,第n次出来就乘n,然后求和的最大值. 题解:用dp[i][j]表示i~j区间和的最大值,然后根据这个状态可以从删前和删后转移过来,推出状态转移方程: dp[i][j]=max(dp[i+1][j]+value[i]*k,dp[i][j-1]+value[j]*k) 1 #include <iostream> 2 #include <algorithm&

51Nod 1009 数字1的个数 | 数位DP

题意: 小于等于n的所有数中1的出现次数 分析: 数位DP 预处理dp[i][j]存 从1~以j开头的i位数中有几个1,那么转移方程为: if(j == 1) dp[i][j] = dp[i-1][9]*2+pow(10,i-1);else dp[i][j] = dp[i-1][9]+dp[i][j-1]; 然后注意下对于每个询问统计的时候如果当前位为1需要额外加上他后面所有位数的个数,就是n%pow(10,i-1); 这样总复杂度log(n)*10 #include <bits/stdc++.

HDU 3555 Bomb (数位DP)

数位dp,主要用来解决统计满足某类特殊关系或有某些特点的区间内的数的个数,它是按位来进行计数统计的,可以保存子状态,速度较快.数位dp做多了后,套路基本上都差不多,关键把要保存的状态给抽象出来,保存下来. 简介: 顾名思义,所谓的数位DP就是按照数字的个,十,百,千--位数进行的DP.数位DP的题目有着非常明显的性质: 询问[l,r]的区间内,有多少的数字满足某个性质 做法根据前缀和的思想,求出[0,l-1]和[0,r]中满足性质的数的个数,然后相减即可. 算法核心: 关于数位DP,貌似写法还是

Codeforces Round #286 (Div. 1) A. Mr. Kitayuta, the Treasure Hunter DP

链接: http://codeforces.com/problemset/problem/506/A 题意: 给出30000个岛,有n个宝石分布在上面,第一步到d位置,每次走的距离与上一步的差距不大于1,问走完一路最多捡到多少块宝石. 题解: 容易想到DP,dp[i][j]表示到达 i 处,现在步长为 j 时最多收集到的财富,转移也不难,cnt[i]表示 i 处的财富. dp[i+step-1] = max(dp[i+step-1],dp[i][j]+cnt[i+step+1]) dp[i+st

bzoj1801: [Ahoi2009]chess 中国象棋 [dp]

Description 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放置方法,中国像棋中炮的行走方式大家应该很清楚吧. Input 一行包含两个整数N,M,中间用空格分开. Output 输出所有的方案数,由于值比较大,输出其mod 9999973 Sample Input 1 3 Sample Output 7 HINT 除了在3个格子中都放满炮的的情况外,其它的都可以. 100%的数据中N,M不超过10050%的数据中,N,M至少有一个数不超过