zoukankan      html  css  js  c++  java
  • Tinkoff Challenge

    D. Presents in Bankopolis
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Bankopolis is an incredible city in which all the n crossroads are located on a straight line and numbered from 1 to n along it. On each crossroad there is a bank office.

    The crossroads are connected with m oriented bicycle lanes (the i-th lane goes from crossroad ui to crossroad vi), the difficulty of each of the lanes is known.

    Oleg the bank client wants to gift happiness and joy to the bank employees. He wants to visit exactly k offices, in each of them he wants to gift presents to the employees.

    The problem is that Oleg don't want to see the reaction on his gifts, so he can't use a bicycle lane which passes near the office in which he has already presented his gifts (formally, the i-th lane passes near the office on the x-th crossroad if and only if min(ui, vi) < x < max(ui, vi))). Of course, in each of the offices Oleg can present gifts exactly once. Oleg is going to use exactly k - 1bicycle lane to move between offices. Oleg can start his path from any office and finish it in any office.

    Oleg wants to choose such a path among possible ones that the total difficulty of the lanes he will use is minimum possible. Find this minimum possible total difficulty.

    Input

    The first line contains two integers n and k (1 ≤ n, k ≤ 80) — the number of crossroads (and offices) and the number of offices Oleg wants to visit.

    The second line contains single integer m (0 ≤ m ≤ 2000) — the number of bicycle lanes in Bankopolis.

    The next m lines contain information about the lanes.

    The i-th of these lines contains three integers uivi and ci (1 ≤ ui, vi ≤ n1 ≤ ci ≤ 1000), denoting the crossroads connected by the i-th road and its difficulty.

    Output

    In the only line print the minimum possible total difficulty of the lanes in a valid path, or -1 if there are no valid paths.

    Examples
    input
    7 4
    4
    1 6 2
    6 2 2
    2 4 2
    2 7 1
    output
    6
    input
    4 3
    4
    2 1 2
    1 3 2
    3 4 2
    4 1 1
    output
    3
    Note

    In the first example Oleg visiting banks by path 1 → 6 → 2 → 4.

    Path 1 → 6 → 2 → 7 with smaller difficulity is incorrect because crossroad 2 → 7 passes near already visited office on the crossroad 6.

    In the second example Oleg can visit banks by path 4 → 1 → 3.

    题目大意:我也不会描述

    区间dp。
    考虑最naive的dp[i][lb][rb][k]表示在现在位置在i,能走的范围是[lb,rb],要在范围内选k个站送礼物的最小难度
    那么可以枚举下一次走到哪里,显然一步只经过一条有向边,因为其他方案都可以用这个方案替代,并且答案不会更劣
    如果下一步往右走,走到to,那么下一次的状态是dp[to][i+1][rb][k-1],同理向左走是dp[to][lb][i-1][k-1],这样需要枚举i,lb,rb,to,k,复杂度是 $kn^4+m$
    然后可以发现,在其中有一维是没用的——向右走不需要左边界,向左走不需要右边界
    则dp[i][b][k]表示走到i,某个方向的边界是b,送了k个礼物
    如果b>i,则是向右走,转移到dp[to][i+1][k-1]与dp[to][b][k-1],向左走同理
    这样需要枚举i,b,to,k复杂度是$kn^3+m$,可过

     1 #include <iostream>
     2 #include <cstdlib>
     3 #include <cstdio>
     4 #include <algorithm>
     5 #include <string>
     6 #include <cstring>
     7 #include <cmath>
     8 #include <map>
     9 #include <stack>
    10 #include <set>
    11 #include <vector>
    12 #include <queue>
    13 #include <time.h>
    14 #define eps 1e-7
    15 #define INF 0x3f3f3f3f
    16 #define MOD 1000000007
    17 #define rep0(j,n) for(int j=0;j<n;++j)
    18 #define rep1(j,n) for(int j=1;j<=n;++j)
    19 #define pb push_back
    20 #define set0(n) memset(n,0,sizeof(n))
    21 #define ll long long
    22 #define ull unsigned long long
    23 #define iter(i,v) for(edge *i=head[v];i;i=i->nxt)
    24 #define max(a,b) (a>b?a:b)
    25 #define min(a,b) (a<b?a:b)
    26 #define print_rumtime printf("Running time:%.3lfs
    ",double(clock())/1000.0);
    27 #define TO(j) printf(#j": %d
    ",j);
    28 //#define OJ
    29 using namespace std;
    30 const int MAXINT = 100010;
    31 const int MAXNODE = 100;
    32 const int MAXEDGE = 2 * 2000;
    33 char BUF, *buf;
    34 int read() {
    35     char c = getchar(); int f = 1, x = 0;
    36     while (!isdigit(c)) {if (c == '-') f = -1; c = getchar();}
    37     while (isdigit(c)) {x = x * 10 + c - '0'; c = getchar();}
    38     return f * x;
    39 }
    40 char get_ch() {
    41     char c = getchar();
    42     while (!isalpha(c)) c = getchar();
    43     return c;
    44 }
    45 //------------------- Head Files ----------------------//
    46 int dis[MAXNODE][MAXNODE], n, K, m, cnt;
    47 int dp[MAXNODE][MAXNODE][MAXNODE];
    48 //now Oleg is at pos i,and have already given out k-1 presents in bank office 1..i-1, 1 in office i, minimum difficulty
    49 //and Oleg can go no further than j
    50 void get_input();
    51 void work();
    52 int main() {
    53     get_input();
    54     work();
    55     return 0;
    56 }
    57 void work() {
    58     memset(dp, INF, sizeof(dp));
    59     int ans = INF;
    60     rep1(i, n)rep1(j, n) dp[i][j][1] = 0; //Oleg can start anywhere,and the first step should always be gifting a present
    61     for (int k = 2; k <= K; k++) { //k in dp
    62         for (int i = 1; i <= n ; i++) { //i in dp
    63             for (int j = i + k - 1; j <= n; j++) { //j in dp
    64                 for (int prv = i + 1; prv <= j; prv++) {  //go right
    65                     dp[i][j][k] = min(dp[i][j][k], min(dp[prv][j][k - 1], dp[prv][i + 1][k - 1]) + dis[i][prv]);
    66                 }
    67             }
    68             for (int j = i - k + 1; j > 0 ; j--) { //j in dp
    69                 for (int prv = i - 1; prv >= j; prv--) { //go left
    70                     dp[i][j][k] = min(dp[i][j][k], min(dp[prv][j][k - 1], dp[prv][i - 1][k - 1]) + dis[i][prv]);
    71                 }
    72             }
    73         }
    74     }
    75     rep1(i, n) rep1(j, n) ans = min(ans, dp[i][j][K]);
    76     printf("%d
    ", (ans == INF) ? -1 : ans);
    77 }
    78 void get_input() {
    79     memset(dis, INF, sizeof(dis));
    80     n = read(); K = read();
    81     m = read();
    82     rep0(i, m) {
    83         int u = read(), v = read(), c = read();
    84         dis[u][v] = min(dis[u][v], c);
    85     }
    86 }
    许愿弥生改二
  • 相关阅读:
    jQuery禁用或启用
    ASP.NET MVC一次删除多笔记录
    在你的ASP.NET MVC中使用查找功能
    Get radio selected value
    绑定一个值给radio
    ASP.NET MVC实现权限控制
    为Guid数据类型的属性(property)赋值
    Razor语法中绑定一个值给checkbox
    判断IEnumerable<T>集合中是否包含有T对象
    SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.
  • 原文地址:https://www.cnblogs.com/LoveYayoi/p/6756579.html
Copyright © 2011-2022 走看看