zoukankan      html  css  js  c++  java
  • 1570. Eating High 夜

    http://acm.timus.ru/problem.aspx?space=1&num=1570

    此题如果只求最少花费的话,就可以简单的dp或是背包就可以了

    难就难在在选择路径上有困难  应该在记录路径时 记下所有可能是最优的路径 排除一定不是最优的路径

    然后选择一条最优的总路径

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<set>
    #include<map>
    #include<string>
    #include<queue>
    #include<stack>
    #include <iomanip>
    using namespace std;
    #define LL long long
    const double eps=1e-6;
    const int INF=0x3f3f3f3f;
    const int N=40005;
    const int M=105;
    struct node
    {
        string name;
        int cost;
        int weight;
    }mem[M];
    int dp[N],num[N],f[N];
    vector<int>vtf[N],vtnum[N];
    int sum[M];
    int n,m;
    bool cmp(node x,node y)
    {
        return x.cost<y.cost;
    }
    void packComplete(int k,int cost,int weight,int V)
    {
        for(int v=cost;v<=V;++v)
        {
            if(v-cost>=m)
            break;
            if(dp[v-cost]+weight>dp[v])
            continue;
            if(dp[v-cost]+weight<dp[v])
            {
                vtf[v].clear();vtnum[v].clear();
                dp[v]=dp[v-cost]+weight;
                num[v]=num[v-cost]+((f[v-cost]==k)?0:1);
                vtf[v].push_back(k);vtnum[v].push_back(num[v]);
                f[v]=k;
            }else if(num[v-cost]+((f[v-cost]==k)?0:1)>num[v])
            {
                num[v]=num[v-cost]+((f[v-cost]==k)?0:1);
                vtf[v].push_back(k);vtnum[v].push_back(num[v]);
                f[v]=k;
            }
        }
    }
    int main()
    {
        //freopen("data.in","r",stdin);
        while(cin>>n>>m)
        {
            m=int(m*1000+eps);
            int V=N-5;
            for(int i=1;i<=n;++i)
            {
                double ftmp;
                cin>>mem[i].name>>mem[i].weight>>ftmp;
                mem[i].cost=int(ftmp*1000+eps);
            }
            sort(mem+1,mem+n+1,cmp);
            memset(f,0,sizeof(f));
            memset(num,0,sizeof(num));
            for(int i=1;i<=V;++i)
            dp[i]=INF;
            dp[0]=0;
            for(int i=1;i<=n;++i)
            packComplete(i,mem[i].cost,mem[i].weight,V);
            memset(sum,0,sizeof(sum));
            int k=V;
            for(int i=m;i<V;++i)
            if(dp[i]<dp[k]||(dp[i]==dp[k]&&num[i]>num[k]))
            k=i;
            cout<<dp[k]<<endl;
            int pnum=num[k],pk=-1;
            while(k!=0)
            {
                for(unsigned int i=0;i<vtf[k].size();++i)
                {
                    if(vtnum[k][i]+((vtf[k][i]==pk||pk==-1)?0:1)==pnum)
                    {
                        pnum=vtnum[k][i];
                        pk=vtf[k][i];
                        ++sum[pk];
                        k=k-mem[pk].cost;
                        break;
                    }
                }
            }
            for(int i=1;i<=n;++i)
            if(sum[i]!=0)
            cout<<mem[i].name<<" "<<sum[i]<<endl;
        }
        return 0;
    }
    

      

  • 相关阅读:
    不用google 是不行的
    一些主题
    腾讯cdc空间
    断言assert的使用
    malloc()和free()的相关知识
    linux上面的sz,rz命令与ssh的配合
    寻找第k小的元素
    c语言中字符串处理函数
    详解之#ifdef和#ifndef
    搭建测试环境linux静态链接库与动态链接库的区别及动态库的创建
  • 原文地址:https://www.cnblogs.com/liulangye/p/2948590.html
Copyright © 2011-2022 走看看