zoukankan      html  css  js  c++  java
  • 2198: 小P当志愿者送餐

    题目描述
    在ICPC程序设计大赛期间,小P作为志愿者的任务是给各个学校送盒饭,小P一次最多可以携带M份盒饭。总共有N个学校来参加比赛,这N个学校的休息点在一条笔直的马路边一字排开,路的一头是小P取盒饭的地方,假设为原点,每两个相邻点之间,小明需要行走15秒,包括从原点到第一个休息点,交付一份盒饭需要3秒时间。从第一个休息点到第N个休息点需要的盒饭数分别为 a1, a2, a3..., an。 问小P最短需要多少时间把全部盒饭送完并回到原点。 
    输入
    第一行输入一个正整数T,表示有T组测试数据,每组占两行,第一行两个整数M、N(0<M,N<50),第二行输入N个整数a1  a2  a3 ...an (0<=a1....an<50) 
    输出
    每行输出一个整数,对应一组测试数据,表示小P送完全部盒饭并返回原点的总时间(秒)。  
    样例输入 Copy
    2
    18 2
    8 6
    10 3
    5 0 8
    样例输出	Copy
    102
    159
    提示
    消耗的时间最少只由走的路程最短决定,每一趟来回走的路程是这一次送餐的最远的点距离原点的两倍。
    

    我的错误:

    //M份盒饭。  总共有N个学校来参加比赛
    //每两个相邻点之间,小明需要行走15秒
    //交付一份盒饭需要3秒时间
    //102=15*(n*2)+(A1+A2+An)*3
    //a1 a2 a3 a4 
    #include<iostream>
    using namespace std;
    int main()
    
    {
        int t,n,sum=0,book,a,b,i,j;//book表示手里拿的东西 t表示时间 
        cin>>n;//几组数据 
        while(n--){ 
            cin>>a>>b;
            int arr[b];
            book=a;
            t=0; 
            sum=0;
            for( i=0;i<b;i++) {
            cin>>arr[i];
            sum+=arr[i];}
            
            for(j=b-1;j>=0;j--){
                book=book-arr[j];
                while(book<=0){
                    if(i==0&&book==0) break;
                    t+=(j+1)*15*2;
                    book=book+a;
                }
            }
            t=t+b*15*2+sum*3;
            cout<<t<<endl;
        } 
        
    }
    View Code

    错误分析主要是送最远的饭的目标寻找没考虑,考虑后正确

    //M份盒饭。  总共有N个学校来参加比赛
    //每两个相邻点之间,小明需要行走15秒
    //交付一份盒饭需要3秒时间
    //102=15*(n*2)+(A1+A2+An)*3
    //a1 a2 a3 a4 
    #include<iostream>
    using namespace std;
    int main()
    
    {
        int t,n,sum=0,book,a,b,i,j,q;//book表示手里拿的东西 t表示时间 
        cin>>n;//几组数据 
        while(n--){ 
            cin>>a>>b;
            int arr[b];
            book=a;
            t=0; 
            sum=0;
            for( i=0;i<b;i++) {
            cin>>arr[i];
            sum+=arr[i];
            if(arr[i]>0) q=i; 
            }
            
            for(j=q;j>=0;j--){
                book=book-arr[j];
                while(book<0){
                    t+=(j+1)*15*2;
                    book=book+a;
                }
            }
            t=t+(q+1)*15*2+sum*3;
            cout<<t<<endl;
        } 
        
    }
    View Code

    同学用的贪心算法:

    #include <stdio.h>
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int INF = 0x3f3f3f3f;
    const ll LINF = 0x3f3f3f3f3f3f3f3f;
    const int N = 100;
    int a[N];
    
    int main()
    {
    #ifdef LOCAL
        freopen("C:/input.txt", "r", stdin);
    #endif
        int T;
        cin >> T;
        while (T--)
        {
            int m, n, p = 0; //p最后一个有效点
            scanf("%d%d", &m, &n);
            ll ans = 0;
            for (int i = 1; i <= n; ++i)
            {
                scanf("%d", &a[i]);
                if (a[i])
                    p = i;
            }
            while (p)
            {
                ans += p * 30; //到p再回原点代价
                int t = m; //身上所带物品
                while (p && t)
                {
                    int e = min(t, a[p]); //交付
                    t -= e;
                    a[p] -= e;
                    ans += e * 3; //交付代价
                    while (p && !a[p]) //如果当前点已经送完则移动p
                        p--;
                }
            }
            printf("%lld
    ", ans);
        }
    
        return 0;
    }
    View Code

     分析:

    1.从远往近送,

    2.确定的最远点需要送餐,arr[i]>0

    3.贪心问题,e=min(arr[j],book),很重要

    自己实现,差不多,

    //M份盒饭。  总共有N个学校来参加比赛
    //每两个相邻点之间,小明需要行走15秒
    //交付一份盒饭需要3秒时间
    //102=15*(n*2)+(A1+A2+An)*3
    //a1 a2 a3 a4 
    #include<iostream>
    using namespace std;
    int main()
    
    {
        int t,n,sum=0,book,a,b,i,j,p,e;//book表示手里拿的东西 t表示时间 
        cin>>n;//几组数据 
        while(n--){ 
            cin>>a>>b;
            int arr[b];
            book=a;
            t=0; 
            sum=0;
            for( i=0;i<b;i++) {
            cin>>arr[i];
            sum+=arr[i];
            if(arr[i])  p=i;
            }
            
            for(j=p;j>=0;j--){
                e=min(arr[j],book);
                book-=e;
                arr[j]-=e;
                while(arr[j]>0){
                    t+=(j+1)*15*2;
                    book=a;
                    e=min(arr[j],book);
                    book-=e;
                    arr[j]-=e;
                }
            }
            t=t+(p+1)*15*2+sum*3;
            cout<<t<<endl;
        } 
        
    }
    View Code
  • 相关阅读:
    智能算法浅介模拟退火,遗传算法,禁忌搜索,神经网络等
    shell 字符串操作(长度,查找,替换)详解
    如何实现两个文件相减的功能(剔除)
    shell数值操作(四则运算,浮点数,科学计数法)awk,bc
    CUDA程序优化的记录
    随机化算法模拟退火
    (转)AspNetPager 样式以及使用(漂亮)
    (转)做项目时,如何做比较美观大方的数据输入窗体
    (转)26个Jquery使用小技巧(jQuery tips, tricks & solutions)
    (转)【译】Asp.net MVC并不仅仅只是Linq to SQL
  • 原文地址:https://www.cnblogs.com/helloworld2019/p/10468041.html
Copyright © 2011-2022 走看看