首页 > 其他分享 >动态规划基础

动态规划基础

时间:2023-10-04 16:04:14浏览次数:32  
标签:tmp include const int 基础 && 动态 规划 dp

动态规划

image

方案数问题

image
image
image

例:P1002 [NOIP2002 普及组] 过河卒

解题思路

image

参考代码
#include <cstdio>
typedef long long LL;
const int N = 25;
int dx[8] = {-2, -2, -1, -1, 1, 1, 2, 2};
int dy[8] = {-1, 1, -2, 2, -2, 2, -1, 1};
bool control[N][N];
LL dp[N][N];
int main()
{
	int n, m, x, y;
	scanf("%d%d%d%d", &n, &m, &x, &y);
	for (int i = 0; i < 8; i++) {
		int xx = x + dx[i], yy = y + dy[i];
		if (xx >= 0 && xx <= n && yy >= 0 && yy <= m) control[xx][yy] = true;
	}
	control[x][y] = true;
	for (int i = 0; i <= m; i++) {
		if (control[0][i]) break;
		dp[0][i] = 1;
	}
	for (int i = 0; i <= n; i++) {
		if (control[i][0]) break;
		dp[i][0] = 1;
	}
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			if (control[i][j]) dp[i][j] = 0;
			else dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
	printf("%lld\n", dp[n][m]);
	return 0;
}

例:P1057 [NOIP2008 普及组] 传球游戏

解题思路

image

参考代码
#include <cstdio>
const int N = 35;
int dp[N][N];
int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    dp[0][1] = 1;
    for (int i = 1; i <= m; i++) {
        dp[i][1] = dp[i - 1][n] + dp[i - 1][2];
        dp[i][n] = dp[i - 1][n - 1] + dp[i - 1][1];
        for (int j = 2; j < n; j++)
            dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j + 1];
    }
    printf("%d\n", dp[m][1]);
    return 0;
}

例:P1077 [NOIP2012 普及组] 摆花

解题思路

image

参考代码
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 105;
const int MOD = 1000007;
int a[N], dp[N][N], sum[N];
int getsum(int l, int r) {
	return l > 0 ? (sum[r] + MOD - sum[l - 1]) % MOD : sum[r];
}
int main()
{
	int n, m;
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
	for (int i = 0; i <= m; i++) sum[i] = 1;
	for (int i = 1; i <= n; i++) {
		for (int j = 0; j <= m; j++)
			dp[i][j] = getsum(max(0, j - a[i]), j);
		sum[0] = dp[i][0];
		for (int j = 1; j <= m; j++) sum[j] = (sum[j - 1] + dp[i][j]) % MOD;
	}
	printf("%d\n", dp[n][m]);
	return 0;
}

最优解问题

image

例:P1216 [USACO1.5] [IOI1994]数字三角形 Number Triangles

解题思路

image
image
image
image

参考代码
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1005;
int a[N][N], dp[N][N];
int main()
{
    int r;
    scanf("%d", &r);
    for (int i = 1; i <= r; i++)
        for (int j = 1; j <= i; j++)
            scanf("%d", &a[i][j]);
    dp[1][1] = a[1][1];
    for (int i = 2; i <= r; i++) {
        dp[i][1] = dp[i - 1][1] + a[i][1];
        dp[i][i] = dp[i - 1][i - 1] + a[i][i];
        for (int j = 2; j < i; j++) 
            dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1]) + a[i][j];
    }
    int ans = 0;
    for (int i = 1; i <= r; i++) ans = max(ans, dp[r][i]);
    printf("%d\n", ans);
    return 0;
}

例:P1006 [NOIP2008 提高组] 传纸条

解题思路

image
image
image

参考代码
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 55;
int dp[N][N][N][N], a[N][N];
int main()
{
    int m, n;
    scanf("%d%d", &m, &n);
    for (int i = 1; i <= m; i++)
        for (int j = 1; j <= n; j++)
            scanf("%d", &a[i][j]);
    for (int i = 1; i <= m; i++)
        for (int j = 1; j <= n; j++)
            for (int k = 1; k <= m; k++)
                for (int l = 1; l <= n; l++)
                    dp[i][j][k][l] = -1;
    for (int i = 1; i <= m; i++)
        for (int j = 1; j <= n; j++)
            for (int k = 1; k <= m; k++) {
                int l = i + j - k;
                if (i * j * k * l == 1) dp[i][j][k][l] = a[1][1];
                else {
                    // (i-1,j) (i,j-1)
                    // (k-1,l) (k,l-1)
                    int tmp = -1;
                    if (i > 1 && k > 1) 
                        tmp = max(tmp, dp[i - 1][j][k - 1][l]);
                    if (i > 1 && l > 1) 
                        tmp = max(tmp, dp[i - 1][j][k][l - 1]);
                    if (j > 1 && k > 1)
                        tmp = max(tmp, dp[i][j - 1][k - 1][l]);
                    if (j > 1 && l > 1)
                        tmp = max(tmp, dp[i][j - 1][k][l - 1]);
                    if (tmp == -1) dp[i][j][k][l] = -1;
                    else dp[i][j][k][l] = tmp + a[i][j] + a[k][l];
                    if (i == k && j == l && (i != m || j != n)) 
                        dp[i][j][k][l] = -1;
                }
            }
    printf("%d\n", dp[m][n][m][n]);
    return 0;
}

例:P7074 [CSP-J2020] 方格取数

解题思路

image
image

参考代码
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 1005;
const LL INF = 1e11;
int a[N][N];
LL dp[N][N][3]; // 0: from up, 1 from down, 2 from left
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", &a[i][j]);
            dp[i][j][0] = dp[i][j][1] = dp[i][j][2] = -INF;
        }
    dp[1][1][0] = dp[1][1][1] = dp[1][1][2] = a[1][1];
    for (int i = 2; i <= n; i++) dp[i][1][0] = dp[i - 1][1][0] + a[i][1];
    for (int j = 2; j <= m; j++) {
        for (int i = 1; i <= n; i++) {
            LL from = max(dp[i][j - 1][0], max(dp[i][j - 1][1], dp[i][j - 1][2]));
            if (from != -INF) dp[i][j][2] = from + a[i][j];
        }
        for (int i = 2; i <= n; i++) {
            LL from = max(dp[i - 1][j][0], dp[i - 1][j][2]);
            if (from != -INF) dp[i][j][0] = from + a[i][j]; 
        }
        for (int i = n - 1; i >= 1; i--) {
            LL from = max(dp[i + 1][j][1], dp[i + 1][j][2]);
            if (from != -INF) dp[i][j][1] = from + a[i][j];
        }
    }
    printf("%lld\n", max(dp[n][m][0], max(dp[n][m][1], dp[n][m][2])));
    return 0;
}

标签:tmp,include,const,int,基础,&&,动态,规划,dp
From: https://www.cnblogs.com/ronchen/p/17742324.html

相关文章

  • 2023-2024-1 20231319《计算机基础与程序设计》第1周学习总结
    《计算机基础与程序设计》第1周学习总结说明班级:2023-2024-1-计算机基础与程序设计作业要求:2023-2024-1《计算机基础与程序设计》教学进程作业目标:快速浏览一遍教材,并提出问题问题第一章1.信息隐藏是如何通过抽象实现的?2.云计算是如何脱离硬件而实现的,真的能完全脱离硬件......
  • 两种方法获取电话区号,检验我们对Excel基础知识储备的反应能力!
    1职场实例小伙伴们大家好,今天我们专门拿出一个篇幅讲解一下如何在Excel中提取座机电话的区号。如下图所示:是一张各个单位的联系信息,其中的B列为座机电话号码,座机电话号码有一个特点:就是有一个间隔符“-”将一串数字分成了左右两段,左段数字为区号,右段数字为号码。现在我们需要在C列......
  • 2023-2024-1学年 学号20231317 《计算机基础与程序设计》第二周学习总结
    学期(如2023-2024-1)学号(如:20231317)《计算机基础与程序设计》第二周学习总结作业信息这个作业属于哪个课程<班级的链接>(如2023-2024-1-计算机基础与程序设计)这个作业要求在哪里<作业要求的链接>(如2023-2024-1计算机基础与程序设计第二周作业)这个作业的目标<分别......
  • 安装Linux操作系统,学习Linux基础
    安装Linux操作系统安装Linux操作系统实践学习“别出心裁的Linux命令学习法”1、ls命令2、man命令3、cheat命令实践学习“Linux基础入门(新版)”......
  • python基础操作练习题
    使用版本:python3.6.8IDE:pycharm前言这些练习题是在神经网络与深度学习课程上老师提供的,原因是有些同学没学过python,作为简单的练手习题。题目都很简单,加上python本身也比较简单,有些题目的作答可以一行代码实现(虽然可读性就下降了)。练习题2.1数位之和编写程序,输入一个正......
  • 【后端开发】01-Java基础语法
    Java基础语法目录1.概述1.1.语言特性1.2.开发平台1.3.开发环境1.4.开发步骤1.5.注释2.变量与运算符2.1.关键字/保留字2.2.标识符2.3.变量2.4.常用数据类型2.4.1.基本数据类型(8种)2.4.2.引用数据类型2.4.3.数据类型转换2.5.运算符2.5.1.算术运算符(7个)2.5.2.关系运......
  • 网络基础知识
    ==============================掩码位变长24掩码位/22借2位1变4  主机1024-2        /21借3位1变8  主机2048-2        /20 借4位1变16 主机4096-2十进制掩码    掩码长度   主机数目   0    ......
  • Java语言基础知识全总结
    一.Java的优点1.      跨平台性。一次编译,到处运行。Java编译器会将Java代码编译成能在JVM上直接运行的字节码文件,C++会将源代码编译成可执行的二进制代码文件,所以C++执行速度快2.      纯面向对象。Java所有的代码都必须在类中书写。C++兼具面向对象和面向过程的特......
  • 20213227《计算机基础与程序设计》第一周学习总结
    作业信息1.作业属于哪个课程:https://edu.cnblogs.com/campus/besti/2023-2024-1-CFAP2.这个作业要求在哪里:https://edu.cnblogs.com/campus/besti/2022-2023-1-CFAP/homework/127543.作业的目标:快速浏览教材《计算机科学概论》,提出自己不懂或最想解决的问题4.作业正文:第一章......
  • 3.Maven基础概念-坐标
    1.maven仓库地址https://repo1.maven.org/maven2/https://mvnrepository.com/2.什么是坐标Maven中坐标用户描述仓库中资源的位置3.maven坐标主要组成groupld:定义当前Maven项目隶属组织名称(通常是域名反写,例如:orgmybatis)artifactld:定义当前Maven项目名称(通常是模块名称......