Tinkoff Challenge - Elimination Round D. Presents in Bankopolis(区间DP)
2017-05-28 11:41
309 查看
http://codeforces.com/contest/793/problem/D
题意:
给出一些点和他们之间的距离,是有向的,这些点从1~n顺序排列,现在选出k个点组成一条路径,使他们之间的距离最短,要求是在路径中,一个被访问过的点不会经过两次或以上。
比如,你访问了1~6这条边,那么你已经访问了1和6这两个点,接下来你就不可以访问5~7这条边了,因为他们之间有6这个点。
思路:
区间dp题。
区间dp的话,递推和记忆化搜索都是可以的。
d【i】【l】【r】【dir】表示当前访问第i次时,在区间【l,r】内的最短距离,并且此时位于dir端,0表示在左端,1表示在右端。
那么这个状态肯定来源于它区间之内的状态。
现在我们假设temp是处于【l,r】之间一个点,那么【l,r】区间的最短距离可以来源于【l,temp】或者【temp,r】。
这样状态转移方程就是:
当然了,在右端时的状态转移方程也是差不多的。
题意:
给出一些点和他们之间的距离,是有向的,这些点从1~n顺序排列,现在选出k个点组成一条路径,使他们之间的距离最短,要求是在路径中,一个被访问过的点不会经过两次或以上。
比如,你访问了1~6这条边,那么你已经访问了1和6这两个点,接下来你就不可以访问5~7这条边了,因为他们之间有6这个点。
思路:
区间dp题。
区间dp的话,递推和记忆化搜索都是可以的。
d【i】【l】【r】【dir】表示当前访问第i次时,在区间【l,r】内的最短距离,并且此时位于dir端,0表示在左端,1表示在右端。
那么这个状态肯定来源于它区间之内的状态。
现在我们假设temp是处于【l,r】之间一个点,那么【l,r】区间的最短距离可以来源于【l,temp】或者【temp,r】。
这样状态转移方程就是:
d[i][l][r][0]=min(d[i][l][r][0],d[i-1][l][temp][1]+dis); d[i][l][r][0]=min(d[i][l][r][0],d[i-1][temp][y][0]+dis);
当然了,在右端时的状态转移方程也是差不多的。
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<vector> #include<stack> #include<queue> #include<cmath> #include<map> using namespace std; typedef long long LL; typedef pair<int,int> pll; const int inf=0x3f3f3f3f; const int maxn=80+5; int n,m,k; int ans; vector<pll> G[maxn]; int d[maxn][maxn][maxn][2]; int main() { //freopen("D:\\input.txt","r",stdin); while(~scanf("%d%d",&n,&k)) { memset(d,0,sizeof(d)); for(int i=1;i<=n;i++) G[i].clear(); ans=inf; scanf("%d",&m); for(int i=1;i<=m;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); G[u].push_back(make_pair(v,w)); //这样的话不需要考虑重边的问题 } if(k==1) {puts("0");continue;} //1的时候特判一下 for(int i=1;i<k;i++) { for(int l=n;l>=0;l--) { for(int r=l+1;r<=n+1;r++) { d[i][l][r][0]=inf; for(int j=0;j<G[l].size();j++) { int temp=G[l][j].first; int dis=G[l][j].second; if(l<temp && temp<r) { d[i][l][r][0]=min(d[i][l][r][0],d[i-1][l][temp][1]+dis); d[i][l][r][0]=min(d[i][l][r][0],d[i-1][temp][r][0]+dis); } } d[i][l][r][1]=inf; for(int j=0;j<G[r].size();j++) { int temp=G[r][j].first; int dis=G[r][j].second; if(l<temp && temp<r) { d[i][l][r][1]=min(d[i][l][r][1],d[i-1][l][temp][1]+dis); d[i][l][r][1]=min(d[i][l][r][1],d[i-1][temp][r][0]+dis); } } if(i==k-1) { ans=min(ans,d[i][l][r][0]); ans=min(ans,d[i][l][r][1]); } } } } if(ans==inf) puts("-1"); else printf("%d\n",ans); } return 0; }
相关文章推荐
- CF-Tinkoff Challenge-Elimination Round-D-Presents in Bankopolis
- Codeforces Round #189 (Div. 2) D. Psychos in a Line 单调队列dp
- Presents in Bankopolis CodeForces - 793D
- 8VC Venture Cup 2016 - Elimination Round F. Group Projects(DP)
- 8VC Venture Cup 2016 - Elimination Round F. Group Projects dp
- POJ 1991 Turning in Homework(贪心+区间DP)
- Codeforces 793 D. Presents in Bankopolis
- Codeforces Round #274 Div.1 C Riding in a Lift --DP
- 【树形dp】VK Cup 2012 Round 1 D. Distance in Tree
- Codeforces Round #274 (Div. 2) E:Riding in a Lift DP + 前缀优化
- 【Educational Codeforces Round 6C】【DP or 贪心】Pearls in a Row n个数分最多区间使得每个区间都有重复数
- Bribe the Prisoners——GCJ 2009 Round1C C(区间dp)
- CROC 2016 - Elimination Round (Rated Unofficial Edition) E. Intellectual Inquiry 贪心 构造 dp
- [平衡树 模拟] SnackDown 2017 Online Elimination Round #WIQ Waiting in a Queue
- poj 1991 Turning in Homework(贪心+区间dp)
- 8VC Venture Cup 2016 - Elimination Round F. Group Projects(DP)★ ★
- CROC 2016 - Elimination Round (Rated Unofficial Edition) E. Intellectual Inquiry 贪心 构造 dp
- 【dp+dfs】VK Cup 2012 Round 1-D. Distance in Tree
- 挑战2.7.3 Round 1C 2009 C. Bribe the Prisoners 区间dp
- Educational Codeforces Round 9 E. Thief in a Shop dp fft