zoukankan      html  css  js  c++  java
  • codeforces 793 D. Presents in Bankopolis(记忆化搜索)

    题目链接:http://codeforces.com/contest/793/problem/D

    题意:给出n个点m条边选择k个点,要求k个点是联通的而且不成环,而且选的边不能包含选过的边不能包含以前

    选过的点,问最小的权值是多少。

    题解:像这种取最小的一般可以考虑一下dp,然后再看一下题目,由于每次选的边都不能包括以前选的点,所以每

    选择一条边能选择的区间范围就缩小了。

    设dp[pos][l][r][k](这里可能会有人觉得开80*80*80*80会不会有点大了,自行计算一下不会爆内存的),pos表示当前位置,l表示区间左端点,r表示区间右端点,k表示还剩下多少条边没选当然也可以

    设选了多少条边。附上记忆化搜索代码

    int dfs(int pos , int l , int r , int count) {

        if(dp[pos][l][r][count] != -1) {

            return dp[pos][l][r][count];

        }

        if(count == 1) {

            dp[pos][l][r][count] = 0;

            return 0;

        }

        int sum = inf;

        for(int i = 1 ; i <= n ; i++) {

            if(mmp[pos][i] != inf) {

                if(i > l && i < r) {

                    int sta = l , end = r;

                    if(i < pos) {

                        end = pos;

                    }

                    else {

                        sta = pos;

                    }

                    sum = min(sum , dfs(i , sta , end , count - 1) + mmp[pos][i]);

                }

            }

        }

        dp[pos][l][r][count] = sum;

        return sum;

    }

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #define inf 0X3f3f3f3f
    using namespace std;
    const int M = 82;
    int n , k , m , u , v , c;
    int mmp[M][M] , dp[M][M][M][M];
    int dfs(int pos , int l , int r , int count) {
        if(dp[pos][l][r][count] != -1) {
            return dp[pos][l][r][count];
        }
        if(count == 1) {
            dp[pos][l][r][count] = 0;
            return 0;
        }
        int sum = inf;
        for(int i = 1 ; i <= n ; i++) {
            if(mmp[pos][i] != inf) {
                if(i > l && i < r) {
                    int sta = l , end = r;
                    if(i < pos) {
                        end = pos;
                    }
                    else {
                        sta = pos;
                    }
                    sum = min(sum , dfs(i , sta , end , count - 1) + mmp[pos][i]);
                }
            }
        }
        dp[pos][l][r][count] = sum;
        return sum;
    }
    int main() {
        scanf("%d%d" , &n , &k);
        scanf("%d" , &m);
        memset(mmp , inf , sizeof(mmp));
        for(int i = 0 ; i < m ; i++) {
            scanf("%d%d%d" , &u , &v , &c);
            mmp[u][v] = min(mmp[u][v] , c);
        }
        memset(dp , -1 , sizeof(dp));
        int ans = inf;
        for(int i = 1 ; i <= n ; i++) {
            ans = min(ans , dfs(i , 0 , n + 1 , k));
        }
        if(ans == inf) {
            printf("-1
    ");
        }
        else {
            printf("%d
    " , ans);
        }
        return 0;
    }
    
  • 相关阅读:
    PyDev for eclipse 插件下载地址
    Impala SQL 语言元素(翻译)[转载]
    oracle9i-11.2安装包及补丁包下载链接
    oracle link的创建过程
    Oracle 查询历史数据(转帖)
    Alpha、Beta、RC、GA版本的区别
    oracle wm_concat(column)函数的使用
    Quest.Central.for.DB2.v5.0.2.4下载地址
    Hadoop 管理工具HUE配置-初始配置
    maven编译下载源码
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/6758247.html
Copyright © 2011-2022 走看看