• HDU_3339 In Action(Dijkstra + DP)


      个人感觉这个题挺好,用到了 最短路+DP,题意很容易就看出来了,其实就是0-1背包问题,状态转移方程:dp[j] = min(dp[j], dp[j-v[i]] + w[i]), 背包容量V = sum(v[0]+v[1] +...+v[n]},]其中每点的power为v[i], 0点到i点的最短路为w[i];然后再在i = [sum/2+1, sum]范围内找min(dp[i])。

      ps:偶悲剧的把i的范围写成i = [sum/2, sum]了,贡献无数WA。。。郁闷!!!

    My Code:

    #include <iostream>
    #include
    <cstdio>
    #include
    <cstring>

    using namespace std;

    const int N = 105;
    const int inf = 0x6ffffff;

    int dis[N][N];
    int dp[N*N];
    int vis[N];
    int low[N];
    int v[N];

    int Dijkstra(int n)
    {
    int flag, i, j, min;
    for(i = 0; i <= n; i++)
    {
    low[i]
    = dis[0][i];
    vis[i]
    = 0;
    }
    vis[
    0] = 1;
    for(i = 0; i < n; i++)
    {
    min
    = inf; flag = -1;
    for(j = 0; j <= n; j++)
    {
    if(min > low[j] && !vis[j])
    {
    min
    = low[j];
    flag
    = j;
    }
    }
    if(flag == -1)
    break;
    vis[flag]
    = 1;
    for(j = 0; j <= n; j++)
    {
    if(!vis[j] && dis[flag][j] < inf)
    {
    if(low[j] > dis[flag][j] + low[flag])
    low[j]
    = dis[flag][j] + low[flag];
    }
    }
    }
    if(flag != -1)
    return 1;
    return 0;
    }

    int main()
    {
    //freopen("data.in", "r", stdin);

    int T;
    scanf(
    "%d", &T);
    while(T--)
    {
    int n, m, i, j, a, b, c, sum = 0;
    scanf(
    "%d%d", &n, &m);
    for(i = 0; i <= n; i++)
    for(j = 0; j <= n; j++)
    if(i == j)
    dis[i][j]
    = 0;
    else
    dis[i][j]
    = inf;
    while(m--)
    {
    scanf(
    "%d%d%d", &a, &b, &c);
    if(c < dis[a][b])
    dis[a][b]
    = dis[b][a] = c;
    }

    v[
    0] = 0;
    for(i = 1; i <= n; i++)
    {
    scanf(
    "%d", &v[i]);
    sum
    += v[i];
    }

    if(!Dijkstra(n))
    {
    printf(
    "impossible\n");
    continue;
    }

    for(i = 1; i <= sum; i++)
    dp[i]
    = inf;

    dp[
    0] = 0;
    for(i = 0; i <= n; i++)
    for(j = sum; j >= v[i]; j--)
    if(dp[j] > dp[j-v[i]]+low[i])
    dp[j]
    = dp[j-v[i]]+low[i];
    int min = inf;
    for(i = sum/2+1; i <= sum; i++)
    if(min > dp[i])
    min
    = dp[i];
    printf(
    "%d\n", min);
    }
    return 0;
    }
  • 相关阅读:
    asp.net大文件断点续传
    JS大文件上传解决方案
    B/S大文件上传解决方案
    B/S上传整个文件夹
    网页上传整个文件夹
    POJ 1068 Parencodings
    74LS85 比較器 【数字电路】
    二叉树的建立与先序,后序,中序输出
    Android 学习之 开源项目PullToRefresh的使用
    理解矩阵及谱聚类小记
  • 原文地址:https://www.cnblogs.com/vongang/p/2170004.html
Copyright © 2020-2023  润新知