习题动态规划!

Posted dprswdr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了习题动态规划!相关的知识,希望对你有一定的参考价值。

本文中的习题来自 Loi_DQS dalao整理的DP学习资料

1.【codevs1220】数字三角形问题

记忆化搜索:

技术分享图片
 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 const int sz=1000+50;
 5 int map[sz][sz],dp[sz][sz];
 6 int n;
 7 int dfs(int i,int j)
 8 {
 9     if(i==n) return map[i][j];
10     if(dp[i+1][j]==0) dp[i+1][j]=dfs(i+1,j);
11     if(dp[i+1][j+1]==0) dp[i+1][j+1]=dfs(i+1,j+1);
12     return dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+map[i][j];
13 }
14 int main()
15 {
16     scanf("%d",&n);
17     for(int i=1;i<=n;i++)
18         for(int j=1;j<=i;j++)
19             scanf("%d",&map[i][j]);
20     printf("%d",dfs(1,1));
21     return 0;
22 }
View Code

顺推:

技术分享图片
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int sz=1000+50;
 6 int map[sz][sz],dp[sz][sz];
 7 int main()
 8 {
 9     int n;
10     scanf("%d",&n);
11     for(int i=1;i<=n;i++)
12         for(int j=1;j<=i;j++)
13             scanf("%d",&map[i][j]);
14     for(int i=1;i<=n;i++)
15         for(int j=1;j<=i;j++)
16             dp[i][j]=max(dp[i-1][j],dp[i-1][j-1])+map[i][j];
17     int ans=-999;
18     for(int i=1;i<=n;i++)
19         ans=max(ans,dp[n][i]);
20     printf("%d",ans);
21     return 0;
22 }
View Code

逆推:

技术分享图片
#include<cstdio>
#include<algorithm>
using namespace std;
const int sz=1000+50;
int map[sz][sz],dp[sz][sz];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=i;j++)
            scanf("%d",&map[i][j]);
    for(int i=n;i>=0;i--)
        for(int j=1;j<=i;j++)
            dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+map[i][j];
    printf("%d",dp[1][1]);
    return 0;
}
View Code

2.【codevs1576】最长上升子序列(LIS)问题

常规做法

技术分享图片
#include<cstdio>
#include<algorithm>
using namespace std;
const int sz=5000+50;
int num[sz],dp[sz];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&num[i]);
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        dp[i]=1;//初始化 以i结尾的LIS长度最小为1 
        for(int j=1;j<i;j++)
            if(num[j]<num[i])
                dp[i]=max(dp[i],dp[j]+1);
        ans=max(ans,dp[i]);
    }
    printf("%d",ans);
    return 0;
}
View Code

O(nlogn)做法。。。

3.方格取数问题

技术分享图片
#include<cstdio>
#include<algorithm>
using namespace std;
const int sz=5000+50;
int map[sz][sz],dp[sz][sz];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%d",&map[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])+map[i][j];
        }
    printf("%d",dp[n][m]);
    return 0;
}
View Code

4.【codevs1102】01背包问题

滚动数组

技术分享图片
#include<cstdio>
#include<algorithm>
using namespace std;
const int sz=1000+10;
struct node{
    int tim,val;
}th[sz];
int dp[sz];
int main()
{
    int t,m;
    scanf("%d%d",&t,&m);
    for(int i=1;i<=m;i++)
    {
        int tim,val;
        scanf("%d%d",&tim,&val);
        th[i].tim=tim,th[i].val=val;
    }
    for(int i=1;i<=m;i++)
        for(int j=t;j>=th[i].tim;j--)
        {
            dp[j]=max(dp[j],dp[j-th[i].tim]+th[i].val);
        }
    printf("%d",dp[t]);
    return 0;
}
View Code

 

以上是关于习题动态规划!的主要内容,如果未能解决你的问题,请参考以下文章

习题动态规划!

习题讲解 | Google, Facebook高频面试题动态规划(DP)

一些动态规划的练习题

一些动态规划的练习题

动态规划习题本(持续更新)

动态规划习题本(持续更新)