简单dp

一:M * N的方格,一个机器人从左上走到右下,只能向右或向下走。有多少种不同的走法?由于方法数量可能很大,只需要输出Mod 10^9 + 7的结果。

Input

第1行,2个数M,N,中间用空格隔开。(2 <= m,n <= 1000)

Output

输出走法的数量。

Input示例

2 3

Output示例

3

 每次算得都是上方跟左方的和计算的,注意每次都要mod,不然会超范围

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <queue>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
const int A=1e9+7;
ll dp[1011][1011];
int main()
{
    ll n,m,i,a,o,T,j,k;
    memset(dp,0,sizeof(dp));
    cin>>m>>n;
    ll maxx=max(m,n);
    for(i=1;i<=maxx;i++)
        dp[1][i]=1;
    for(i=1;i<=maxx;i++)
        dp[i][1]=1;
    for(i=2;i<=1001;i++)
    {
        for(j=2;j<=1001;j++)
        {
            dp[i][j]=(dp[i-1][j]+dp[i][j-1])%A;
        }
    }
    cout<<dp[m][n]%A<<endl;
    return 0;
}

二:最大子段和

N个整数组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的连续子段和的最大值。当所给的整数均为负数时和为0。

例如:-2,11,-4,13,-5,-2,和最大的子段为:11,-4,13。和为20。

Input

第1行:整数序列的长度N(2 <= N <= 50000)
第2 - N + 1行:N个整数(-10^9 <= A[i] <= 10^9)

Output

输出最大子段和。

Input示例

6
-2
11
-4
13
-5
-2

Output示例

20

动态规划算法

假设最大字段和我们设为 M


我们设 1−j 中包括a[j]最大字段和为 b[j]


即:

b[j]=max{0,b[j−1]}+a[j]

 

我们求出包括a[i]−a[n]

的所有最大字段和后,只需要求出这些最大字段和中最大的那个就可以了!
即:

M=max b[j] 1≤j≤n

 

i12345678
a[i]13-53-25-43
b[i]14-1316-23

故可知 M=6

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
const int AA=4e5+7;
map<string,ll> M;
map<string,string> N;
ll a[51010],b[51010];
int main()
{
    ll n,i,maxx=0,c=0;
    cin>>n;
    for(i=0;i<n;i++)
        cin>>a[i];
    b[0]=a[0];
    for(i=1;i<n;i++)
    {
        b[i]=max(c,b[i-1])+a[i];
        maxx=max(maxx,b[i]);
    }
    cout<<maxx<<endl;
    return 0;
}

三:数塔问题   https://blog.csdn.net/ZCY19990813/article/details/82467119

四:

一个N*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,从左上走到右下,只能向下向右走,求能够获得的最大价值。

例如:3 * 3的方格。

 

1 3 3

2 1 3

2 2 1

 

能够获得的最大价值为:11。

Input

第1行:N,N为矩阵的大小。(2 <= N <= 500)
第2 - N + 1行:每行N个数,中间用空格隔开,对应格子中奖励的价值。(1 <= N[i] <= 10000)

Output

输出能够获得的最大价值。

Input示例

3
1 3 3
2 1 3
2 2 1

Output示例

11

思路:转化成子问题,求上面跟前面最大的和自己相加。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
ll p[10101];
ll w[10001];
ll a[1010][1010];
ll dp[1001][1001]={0};
int main()
{
    ll n,i,j;
    cin>>n;
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
           cin>>a[i][j];
    for(i=1;i<n;i++)
        a[0][i]=a[0][i-1]+a[0][i];
    for(i=1;i<n;i++)
        a[i][0]=a[i-1][0]+a[i][0];
    for(i=1;i<n;i++)
    {
        for(j=1;j<n;j++)
        {
            a[i][j]=a[i][j]+max(a[i-1][j],a[i][j-1]);
        }
    }
    cout<<a[n-1][n-1]<<endl;
    return 0;
}

五:

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值