USACO5.4.1 Canada Tour(tour)

本文介绍了一种使用动态规划算法解决特定旅行问题的方法。通过定义状态dp[i][j]表示两个旅行者分别到达i和j点时访问过的城市数量之和,并给出了状态转移方程。最终目标是找到能够到达终点的最大城市数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这道题刚开始搜索加各种优化还是超时,题中所说的只能自西向东定向旅行,实际上取消了该题的后效性,可以用动态规划来做。把返回的路线反向,假定有两个人分别从起点到终点进行旅行,那么整条路线就变成了两条不相交的从起点到终点的路线。

设dp[ i ][ j ]为假定的甲乙两人,甲走到第i个城市,乙走到第j个城市时,两人走过的城市数目的和。(初始时dp[1][1]=1)

状态转移方程:dp[ j ][ i ]=dp[ i ][ j ]=max{ dp[ i ][ k]+1 }(k到j存在飞机航线,1<=k<j) 交换甲乙,则肯定有dp[ j ][ i ]=dp[ i ][ j ]。

由于题中告知必须走到终点才能返回,输出结果一定是max{ dp[ i ][ N] }(i到N存在飞机航线)。 如果没有经过城市数目大于1的可行目标状态,则无法完成这次环游,输出1。

/*
ID:xsy97051
LANG:C++
TASK:tour
*/
#include <iostream>
#include <cstdio>
#include <map>
#include <cstring>
using namespace std;
#define maxint 0x7FFFFFFF;

map<string,int> city;
bool g[105][105];
int dp[105][105];

int main()
{
	freopen("tour.in","r",stdin);
	freopen("tour.out","w",stdout);
	memset(g,0,sizeof(g));
    int n,m;
	string s1,s2;
	cin>>n>>m;
    for(int i=1;i<=n;++i)
    {
		cin>>s1;
		city[s1]=i;
    }
 	for(int i=1;i<=m;i++)
 	{
 		cin>>s1>>s2;
 		int t1=city[s1],t2=city[s2];
		g[t1][t2]=g[t2][t1]=1;
 	}

 	dp[1][1]=1;
 	for(int i=1;i<=n;++i)
 		for(int j=i+1;j<=n;++j)
 		{
 			dp[i][j]=-maxint;
 			for(int k=1;k<j;k++)
 			{
 				if(g[k][j] && dp[i][k]>0 && dp[i][k]>dp[i][j])
		    	dp[i][j]=dp[i][k];
 			}
 			dp[j][i]=++dp[i][j];
 		}
 	
 	int ans=1;
    for(int i=1;i<=n;++i)
		if(g[i][n] && dp[i][n]>ans)
			ans=dp[i][n];
    
    cout<<ans<<endl;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值