• 动态规划题目整理


    dp题目整理

    背包问题

    榨取kkksc03

    因为题目中有两个限制条件,所以并不能当做一般背包问题来做,

    既然限制条件(类似于"体积")多了一个,那么现在维数也多开一维,同时表示其状态

    我们又发现,这个题每种物品(需求)只能取一次,所以这是一道多维0/1背包题目

    那么这题就很好做了

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int n,m,t;
    int dp[205][205];
    int mi[105];
    int ti[105];
    int main(){
    	scanf("%d%d%d",&n,&m,&t);
    	for(int i=1;i<=n;i++)
    		scanf("%d%d",&mi[i],&ti[i]);
    	for(int i=1;i<=n;i++)
    		for(int j=t;j>=ti[i];j--)
    			for(int k=m;k>=mi[i];k--)
    				dp[j][k]=max(dp[j-ti[i]][k-mi[i]]+1,dp[j][k]);
    	printf("%d",dp[m][t]);
    	return 0;
    }
    

    求概率等的题目则更像是数学题,更需要好好分析其中的条件分析式子以推出状态转移方程

    搞笑世界杯

    显然,暴力枚举是不行的,那么现在考虑如何表示状态

    (dp[i][j])表示A种票,B种票分别售出(i)张,(j)张时两人票相同的概率

    首先考虑边界条件,

    如果某一种票已经发完了,那么其概率一定是1,

    就有:(dp[i][0]=dp[0][i]=1)

    然后再考虑转移方程

    对于当前的人,要么发到A种,要么B种,这样一来,其状态就都能够从前面状态转移而来

    也就是都能从(dp[i-1][j])(dp[i][j-1])转移而来

    就是这样:

    (dp[i][j]=(dp[i-1][j]+dp[i][j-1])/2)

    这里除以2的原因是两种情况各占一种,其概率要平均分

    初始化和状态转移分析完了,剩下就只是数据处理部分了

    然后代码长这样:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int n;
    double dp[1255][1255];
    int main(){
    	scanf("%d",&n);
    	n/=2;
    	for(int i=2;i<=n;i++)
    		dp[i][0]=dp[0][i]=1;
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)
    			dp[i][j]=(dp[i-1][j]+dp[i][j-1])/2.0;
    	printf("%0.4lf
    ",dp[n][n]);
    	return 0;
    }
    

    代码同样很短,这就是dp的魅力所在,用极小的篇幅带来不小的思维量

    总之记住一点,dp就是前辈给后辈做出贡献的东西,后辈只能从前辈那里"学到东西"

  • 相关阅读:
    Atitit.atiJsBridge 新特性v7q329
    atitit.userService 用户系统设计 v6 q413
    atitit.userService 用户系统设计 v6 q413
    Atitit.获取某个服务 网络邻居列表 解决方案
    Hasse神舟笔记本卡logo解决,刷BIOS方法,教你修复神船
    Axure RP 8 注册码
    在本地硬盘安装WinPE系统,实现UEFI引导,摆脱U盘
    cmd实现批量文件的base64加密并双击加密文件后正常运行
    cmd的变量总结
    fiddler几种功能强大的用法
  • 原文地址:https://www.cnblogs.com/648-233/p/11346039.html
Copyright © 2020-2023  润新知