POJ 3230 Travel (DP)

题意:有n个城市,一个人从i到j城市时,可以得到income[j]的财富,需要消耗cost[i][j]的财富,也可以选择不动,也就是呆在i城市,那么可以得到income[i]的财富,需要消耗cost[i][i]的财富,但每个城市的incom[]是随天数变化的,求出m天内这个人能获得的最大的财富值。

思路:很明显的dp,用dp[m][i]记录第m天,在第i个城市时所能获得的最大财富值,有一个地方需要注意,就是dp时的初始化,我是把第一天单独处理的,然后普通的dp就可以了。

#include <iostream>
#include
<cstdio>
#include
<algorithm>
#include
<memory.h>
#include
<cmath>
#include
<set>
#include
<bitset>
#include
<vector>
using namespace std;

const int BORDER = (1<<20)-1;
const int MAXSIZE = 37;
const int MAXN = 250;
const int INF = 0x7ffffff;
#define CLR(x,y) memset(x,y,sizeof(x))
#define ADD(x) x=((x+1)&BORDER)
#define IN(x) scanf("%d",&x)
#define OUT(x) printf("%d\n",x)
#define MIN(m,v) (m)<(v)?(m):(v)
#define MAX(m,v) (m)>(v)?(m):(v)
#define ABS(x) (x>0?x:-x)

int n,m;
int arr_dp[MAXN][MAXN],cost[MAXN][MAXN],val[MAXN][MAXN];
int visit[MAXN];
int init()
{
CLR(arr_dp,
0);
CLR(cost,
0);
CLR(val,
0);
CLR(visit,
0);
return 0;
}
int input()
{
int i,j;
for(i = 0; i < n; ++i)
for(j = 0; j < n; ++j)
scanf(
"%d",&cost[i][j]);
for(i = 0; i < m; ++i)
for(j = 0; j < n; ++j)
scanf(
"%d",&val[i][j]);
return 0;
}
int dp()
{
int i,j,tmp,k;
int mmax;
for(i = 1; i < n; ++i)
arr_dp[
0][i] = val[0][i]-cost[0][i];
arr_dp[
0][0] = val[0][0]-cost[0][0];
for(i = 1; i < m; ++i)
{
for(j = 0; j < n; ++j)
{
mmax
= -INF;
for(k = 0; k < n; ++k)
{
if(k == j )
continue;
mmax
= MAX(mmax,arr_dp[i-1][k]-cost[k][j]+val[i][j]);
}
arr_dp[i][j]
= MAX(mmax,arr_dp[i-1][j]-cost[j][j]+val[i][j]);
}
}
mmax
= -INF;
for(i = 0; i < n; ++i)
mmax
= MAX(mmax,arr_dp[m-1][i]);
OUT(mmax);
return 0;
}
int main()
{
int i,j;
while(scanf("%d%d",&n,&m))
{
if(!n && !m)
break;
init();
input();
dp();
}
return 0;
}

原文地址:https://www.cnblogs.com/lvpengms/p/1708793.html