poj3230/2137 动态规划(城市间转移获利)

题意:有n个城市,一个人从城市1出发,每天可以选择继续呆在当前城市或者转移到其他城市,第i天呆在第j个城市的收入为in[i][j],从第i个城市转移到第j个城市的费用out[i][j],求m天后的最大收入。

思路:动态规划。dp[i][j]为第i天在(最终停留在)第j个城市获得的最大收入。每个dp[i][j]由遍历dp[i-1][1...n]得到。dp数组可以用滚动数组优化。

#include <stdio.h>
#include <string.h>
#define N 102
int n,m,dp[N][N];
int out[N][N],in[N][N];
int main(){
	freopen("a.txt","r",stdin);
	while(scanf("%d %d",&n,&m) &&n&&m){
		int i,j,k,res,max;
		for(i = 0;i<n;i++)
			for(j = 0;j<n;j++)
				scanf("%d",&out[i][j]);
		for(i = 0;i<m;i++)
			for(j = 0;j<n;j++)
				scanf("%d",&in[i][j]);
		for(i = 0;i<n;i++)
			dp[0][i] = in[0][i]-out[0][i];
		for(i = 1;i<m;i++){
			for(j = 0;j<n;j++){
				max = dp[i-1][0]+in[i][j]-out[0][j];
				for(k = 1;k<n;k++){
					int temp = dp[i-1][k]+in[i][j]-out[k][j];
					max = max>temp?max:temp;
				}
				dp[i][j] = max;
			}
		}
		res = dp[m-1][0];
		for(i = 1;i<n;i++)
			res = res>dp[m-1][i]?res:dp[m-1][i];
		printf("%d\n",res);
	}
	return 0;
}

2137题意:在二维平面上给出n个点集,在每个点集里面选一个点,把所有的点按照编号连接成一个圈,使圈的长度最短。

思路:动态规划,枚举第一个点集的每一个点,设为起始点,然后动归即可。复杂度O(n*s^3)。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
#define INF 0x3fffffff
#define clr(s,t) memset(s,t,sizeof(s))
#define N 105
#define M 42
double s[N][M][M],dp[N][M];
int num[N];
int n;
struct node{
    int x,y;
}p[N][M];
double dist(struct node a,struct node b){
    return sqrt((double)(a.x-b.x)*(a.x-b.x)+(double)(a.y-b.y)*(a.y-b.y));
}
int main(){
    int i,j,k,a;
    int res = INF;
    scanf("%d",&n);
    for(i = 1;i<=n;i++){
        scanf("%d",&num[i]);
        for(j = 1;j<=num[i];j++)
            scanf("%d %d",&p[i][j].x,&p[i][j].y);
    }
    for(i = 1;i<n;i++)
        for(j = 1;j<=num[i];j++)
            for(k = 1;k<=num[i+1];k++)
                s[i][j][k] = dist(p[i][j],p[i+1][k]);
    for(j = 1;j<=num[n];j++)
        for(k = 1;k<=num[1];k++)
            s[n][j][k] = dist(p[n][j], p[1][k]);
    for(a = 1;a<=num[1];a++){
        for(i = 1;i<=num[2];i++)
            dp[2][i] = s[1][a][i];
        for(i = 3;i<=n;i++)
            for(j = 1;j<=num[i];j++){
                dp[i][j] = INF;
                for(k = 1;k<=num[i-1];k++)
                    dp[i][j] = min(dp[i][j],dp[i-1][k]+s[i-1][k][j]);
            }
        for(i = 1;i<=num[n];i++)
            res = min(res,(int)(100*(dp[n][i]+s[n][i][a])));
    }
    printf("%d\n",res);
    return 0;
}


你可能感兴趣的:(poj3230/2137 动态规划(城市间转移获利))