zoukankan      html  css  js  c++  java
  • P2747 [USACO5.4]周游加拿大Canada Tour DP

    1030考试T4

    ​ 题目大意:

    ​ 小 R 赢得了一张 L 国家环游机票。旅行在这家航空公司开放的最西边的城市开始,然后一直自西向东旅行,直到你到达最东边的城市,再由东向西返回,直到你回到开始的城市。除了旅行开始的城市之外,每个城市只能访问一次,因为开始的城市必定要被访问两次(在旅行的开始和结束)。当然不允许使用其他公司的航线或者用其他的交通工具。给出这个航空公司开放的城市的列表,和两两城市之间的直达航线列表。找出能够访问尽可能多的城市的路线,这条路线必须满足上述条件,也就是从列表中的第一个城市开始旅行,访问到列表中最后一个城市之后再返回第一个城市。

    题目链接

    ​ DP.

    ​ 题目让你找一条从(n)到1.再从1到(n)并且不重复经过点的最长路径.从(n)到1的路径可以看做是从1到(n)的另一条路径,所以我们可以设:

    (f[i][j])表示第一条路径走到(i),第二条路径走到(j)的最长路径,所以最后的答案应该是(max(f[i][n])).保证(i,n)联通.

    ​ 然后转移:(f[i][j] = f[i][k] + 1),保证(k, j)联通,也就是(f[i][k])有值.因为着两条路径可以交换,所以(f[j][i] = f[i][j]).强制(j > i, j > k)是为了防止重复经过一个点.

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 505, M = 3005;
    int n, m, ans;
    string a, b;
    int vis[N][N], f[N][N];
    map <string, int> mp;
    
    int main() {
    	
    	cin >> n >> m;
    	for(int i = 1;i <= n; i++) {
    		cin >> a; mp[a] = i;
    	}
    	for(int i = 1;i <= m; i++) {
    		cin >> a >> b;
    		vis[mp[a]][mp[b]] = vis[mp[b]][mp[a]] = 1;
    	}
    	
    	memset(f, -63, sizeof(f)); f[1][1] = 1;
    	for(int i = 1;i <= n; i++) 
    		for(int j = i + 1;j <= n; j++) 
    			for(int k = 1;k < j; k++) 
    				if(vis[j][k])
    					f[i][j] = f[j][i] = max(f[i][j], f[i][k] + 1);
    	ans = 1;
    	for(int i = 1;i <= n; i++)
    		if(vis[i][n]) ans = max(ans, f[i][n]);
    	printf("%d", ans);
    
    	return 0;
    }
    
  • 相关阅读:
    shiro注解,初始化资源和权限,会话管理
    shiro标签
    20个为前端开发者准备的文档和指南
    Canvas处理头像上传
    Chrome 实用调试技巧
    JS 代码编一个倒时器
    sql server优化
    在线图片压缩网站
    Request.QueryString
    C#网络爬虫
  • 原文地址:https://www.cnblogs.com/czhui666/p/13912573.html
Copyright © 2011-2022 走看看