USACO5.4.1 Canada Tour(tour)

来源:互联网 发布:java http json 编辑:程序博客网 时间:2024/05/22 02:26

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

设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:xsy97051LANG: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;}


0 0
原创粉丝点击