动态规划 III——C - Travel
来源:互联网 发布:复杂网络基础概论 编辑:程序博客网 时间:2024/05/18 01:32
如本题,变化因素有:城市数量、旅游天数、过市费用、从市赚取得钱。计算机语言描述如下(结合题目给出的已有变量名):
n表示城市数量,m表示旅游天数。结合例子,从城市i到城市j的费用可以表示成cost[i][j],至于要呆几天,过市的费用是不受影响的;第i天在城市j赚到的钱可以表示成inc[i][j],至于
昨天从哪个城市来的,并不影响今天在这个城市赚的钱。
(2)理清题意之后,开始看问题。看问题时,同样要把问题的描述转换成计算机语言。
问题文字描述;求3天游历3个城市得到的最大收益。可以用dp[i][j]表示第i天游历城市j得到的最大收益,即是旅游到第i天时人在城市j所得到的最大收益(包括之前得到的收益,
不断累加的一个结果)。
(3)最后分析问题。3天游历3个城市得到的最大收益。(起始站在城市1)下面将问题小化
1、假设一天游历一个城市。
——>这一天我可能在城市1、城市2、城市3。问题解决:求出dp[1][1]、dp[1][2]、dp[1][3]三者的值,再取最大值就好。
——>dp[1][i]=0-cost[1][i]+inc[1][i]; (注意今天的最大收益是有昨天最大收益的累加,第i天的收益也要有前面i-1天的收益累加)2、假设两天游历两个城市。
——>第一天我可能在城市1、城市2、城市3。同假设1,只是不取假设1中的最大值。
——>第二天我可能在城市1、城市2、城市3。问题解决:求出dp[2][1]、dp[2][2]、dp[2][3]三者的值,再取最大值就好。
——>若第二天在城市1,则dp[2][1]=dp[1][i]-cost[i][1]+inc[2][1]; //i指的是:前一天从城市i到城市1(i=1,2,3)——>若第二天在城市2,则dp[2][2]=dp[1][i]-cost[i][2]+inc[2][2]; //i指的是:前一天从城市i到城市2(i=1,2,3)
——>若第二天在城市3,则dp[2][3]=dp[1][i]-cost[i][3]+inc[2][3]; //i指的是:前一天从城市k到城市3(i=1,2,3)
——>dp[2][j]=dp[1][i]-cost[i][j]+inc[2][j]3、假设三天游历三个城市。
——>第一天我可能在城市1、城市2、城市3。同假设1,只是不取假设1中的最大值。
——>第二天我可能在城市1、城市2、城市3。同假设2,只是不取假设2中的最大值。
——>第三天我可能在城市1、城市2、城市3。问题解决:求出dp[3][1]、dp[3][2]、dp[3][3]三者的值,再取最大值就好。——>若第三天在城市1,则dp[3][1]=dp[2][i]-cost[i][1]+inc[3][1]; //i指的是:前一天从城市i到城市1(i=1,2,3)
——>若第三天在城市2,则dp[3][2]=dp[2][i]-cost[i][2]+inc[3][2]; //i指的是:前一天从城市i到城市2(i=1,2,3)——>若第三天在城市3,则dp[3][3]=dp[2][i]-cost[i][3]+inc[3][3]; //i指的是:前一天从城市i到城市3(i=1,2,3)
——>dp[3][j]=dp[2][i]-cost[i][j]+inc[3][j](4)观察:dp[1][i]、dp[2][j]、dp[3][j],可以发现后一个式子的求解只与前一个式子有关。符合(动态规划特征:当前状态与上一状态相关)
写出通用公式——>dp[i][j]=dp[i-1][k]-cost[k][j]+inc[i][j]
1、对通用公式进行分析:1)有三个变量名:i(指天数)、j(指城市)、k(指城市)。
2)变量名变化次数的多少,由多到少排序:k,j,i;3)与公式中变量名相关的因素:k(n),j(n),i(m);由这三点分析能够写出一个大循环(三重)
2、对动态边界进行确定:往往将大循环第一重的第一个赋值(i=1,注意,这时k=1)代入通用公式:dp[1][j]=dp[0][1]-cost[1][j]+inc[1][j]
——>dp[0][1]、cost[1][j]、inc[1][j]就是边界。
——>边界的式子需要在大循环的前面先求解出具体的值。
<span style="font-family: Arial, Helvetica, sans-serif;">下面是伪代码演示:</span>
dp[0][1]=0;for(...;i<=n;...) //包含了cost[1][j]for(...;j<=n;...)scanf(数据输入);for(...;i<=m;..) //包含了inc[1][j]for(...;j<=n;...)scanf(数据输入);for(..;i<=m;..) //(三重)大循环,相当于求出了一个二维数组dp[m][n]for( ...;j<=n;...)for( ...;k<=n;...)dp[i][j]=max(dp[i][j],通用公式) //dp数组要在前面初始化,赋予极小的值(属于技巧性,因为动态肯定要比较,这里是累加性的,只能和自身比较)。方便这里对dp[i][j]和通用公式的初次比较和获取最大值。ans=0; //通过比较dp[3][i]找出最大值,解决问题。这里ans=0和“前面dp数组要在前面初始化,赋予极小的值”的作用一样。for(int i=1;i<=n;i++)ans=max(ans,dp[3][i])
</pre><pre name="code" class="cpp">下面是C++代码演示:
#include<stdio.h>#include<math.h>#include<algorithm>using namespace std;int cost[105][105];int inc[105][105];int dp[105][105];int main(){int n,m;while(scanf("%d%d",&n,&m)){if(!n&&!m)break;for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%d",&cost[i][j]);for(int i=1;i<=m;i++)for(int j=1;j<=n;j++)scanf("%d",&inc[i][j]);memset(dp,-9999999,sizeof(dp));dp[0][1]=0;for(int i=1;i<=m;i++)for(int j=1;j<=n;j++)for(int k=1;k<=n;k++)dp[i][j]=max(dp[i][j],dp[i-1][k]-cost[k][j]+inc[i][j]);int ans=0;for(int i=1;i<=n;i++)ans=max(ans,dp[m][i]);printf("%d\n",ans);}}
- 动态规划 III——C - Travel
- POJ3230 - Travel - 动态规划
- 动态规划 III——A - Railway tickets
- 动态规划 III——B - Apple Catching
- 动态规划 III——D - Max Sequence
- 动态规划详解III
- 动态规划专题(III)
- 动态规划—Problem C
- POJ 3230 Travel 动态规划Dp
- 13.5—动态规划—Best Time to Buy and Sell Sto III
- 动态规划——problem c
- 【C++】 动态规划—矩阵链乘
- ZOJ 3719 Diablo III 动态规划
- 暑假-动态规划 III-(Q - Alignment)
- 暑假-动态规划 III-(X - Cash Machine)
- 暑假-动态规划 III-(V - Coins)
- 暑假-动态规划 III-O - Palindrome
- 暑假-动态规划 III-J - The Peanutsw
- 八数码问题(待
- 7.Hibernate 延迟加载&立即加载
- ios利用单例传值
- 产品需求优先级评估
- C++网络摄像头数据的获取与显示
- 动态规划 III——C - Travel
- 程序中异常控制原则
- 浅谈程序员的英语学习
- 警告: No mapping found for HTTP request with URI [] in DispatcherServlet with name
- maven update error:Cannot nest 'xxx/WEB-INF/classes' inside 'xxx'
- hdu 1007 平面最近点对 分治
- C语言修饰词之violate使用
- Linux系统工程师的必备素质
- POJ 2956 The Pilots Brothers' refrigerator