zoukankan      html  css  js  c++  java
  • dp(过河问题)

    http://codeforces.com/gym/101492/problem/E

    思路:

    按过河时间排序后

    有两种最优策略:

    1.最轻的带最重的过去,

    2.两个最轻的带两个最重的过去。

    每次判断两人,比较两种策略哪个更优。

    样例1:编号为1,2,3,首先1和3先过去,1回来,然后1和2过去,时间是50+30+40=120

    样例2:编号为1,2,3,4,首先1和2先过去,1回来,然后3和4过去,2回来,最后1和2过去,时间是20+10+100+20+20=170

    题目分析:这题看起来似乎是dp的题目,但是看内存和时间,2个循环的时间并不足够。但是稍微分析,其实可以发现,有两种情况:

    假设有编号为1,2,3,4,4个人在A要去B;

    第一种情况:先1+2过去,然后换3+4过去;具体流程是1+2过去,1回来,3+4过去,2回来,此时时间是t1=num[2]+num[1]+num[4]+num[2]=num[2]*2+num[1]+num[4];

    第二种情况:1+4过去,1回来,1+3过去,1回来;也就是通过1来回,逐个过去。时间是t2=num[4]+num[1]+num[3]+num[1]=num[1]*2+num[3]+num[4];

    由上两种情况,总结出选择哪一种过法,可以比较t1和t2的时间取小,也就是看num[2]+num[2]>num[1]+num[3]?t1:t2

    #include <cmath>
    #include <algorithm>
    #include <iostream>
    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <stdio.h>
    #include <set>
    #include <stack>
    #include <string.h>
    #include <vector>
    #include <queue>
    #define ME(x , y) memset(x , y , sizeof(x))
    #define SF(n) scanf("%d" , &n)
    #define rep(i , n) for(int i = 0 ; i < n ; i ++)
    #define INF  0x3f3f3f3f
    using namespace std;
    long long a[100009];
    
    int main()
    {
        int n ;
        while(scanf("%d" , &n) != EOF)
        {
            for(int i = 0 ; i < n ; i++)
            {
                scanf("%lld" , &a[i]);
            }
            sort(a , a + n);
            long long ans = 0 ;
            if(n == 1)
            {
                ans = a[0];
            }
            else
            {
                if(n % 2 == 1)
                {
                    ans += a[0] + a[1] + a[2];
                    for(int i = 4 ; i < n ; i += 2)
                    {
                        ans += min(2 *a[0] + a[i-1] + a[i] , a[0] + 2*a[1] + a[i]);
                    }
                }
                else
                {
                    ans += a[1];
                    for(int i = 3 ; i < n ; i += 2 )
                    {
                        ans += min(2*a[0] + a[i-1] + a[i] , a[0] + 2*a[1] + a[i]);
                    }
                }
            }
            printf("%lld
    " , ans);
    
        }
    
    
    
        return 0 ;
    }

    http://poj.org/problem?id=2573

    另外需要输出具体过程

    //#include <bits/stdc++.h>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <stdio.h>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <string.h>
    #include <vector>
    #define ME(x , y) memset(x , y , sizeof(x))
    #define SF(n) scanf("%d" , &n)
    #define rep(i , n) for(int i = 0 ; i < n ; i ++)
    #define INF  0x3f3f3f3f
    #define mod 20191117
    #define PI acos(-1)
    using namespace std;
    typedef long long ll ;
    int a[1009];
    
    vector<int>v[100009];
    int main()
    {
        int n ;
        scanf("%d" , &n);
        for(int i = 1 ; i <= n ; i++)
        {
            scanf("%d" , &a[i]);
        }
        if(n == 1){
            cout << a[1] << endl;
            cout << a[1] << endl;
            return 0 ;
        }
        sort(a + 1 , a + n + 1);
        int ans = 0 , j , sum = 0;
        for(j = n ; j >= 4 ; j -= 2)
        {
            if(a[j]+a[j-1]+2*a[1] >= a[j]+a[1]+2*a[2])
            {
                sum += a[j]+a[1]+2*a[2] ;
                v[++ans].push_back(a[1]),v[ans].push_back(a[2]);
                v[++ans].push_back(a[1]);
                v[++ans].push_back(a[j-1]), v[ans].push_back(a[j]);
                v[++ans].push_back(a[2]);
            }
            else{
                sum += a[j]+a[j-1]+2*a[1] ;
                v[++ans].push_back(a[1]) , v[ans].push_back(a[j]);
                v[++ans].push_back(a[1]);
                v[++ans].push_back(a[1]), v[ans].push_back(a[j-1]);
                v[++ans].push_back(a[1]);
            }
        }
        if(j == 2)
        {
            sum += a[2] ;
            v[++ans].push_back(a[1]) , v[ans].push_back(a[2]);
        }
        else{
            sum += a[1] + a[2] + a[3];
            v[++ans].push_back(a[1]) , v[ans].push_back(a[3]);
            v[++ans].push_back(a[1]);
            v[++ans].push_back(a[1]) , v[ans].push_back(a[2]);
        }
        cout << sum << endl ;
        for(int i = 1 ; i <= ans ; i++)
        {
            if(v[i].size() == 2)
            {
                cout << v[i][0] << " " << v[i][1] << endl;
            }
            else{
                cout << v[i][0] << endl ;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    Hive优化
    RDD
    从Hadoop MapReduce到Spark
    Spark on yarn模式
    Hive的web端配置——HWI
    Spark环境搭建
    java身份证号校验
    java手机号码、电子邮箱校验
    服务器运维的日常维护工作
    JavaSSM框架简介
  • 原文地址:https://www.cnblogs.com/nonames/p/11329547.html
Copyright © 2011-2022 走看看