• 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
  • 相关阅读:
    PHP、JAVA、C#、Object-C 通用的DES加密
    xtraScrollableControl 滚动条随鼠标滚动
    C#让TopMost窗体弹出并置顶层但不获取当前输入焦点的终极办法
    C#获取“所有用户桌面”的路径
    C#如何获取快捷方式指向的目标文件
    10
    09
    新浪微博中tableview中头部信息
    ASIHTTPRequest类库简介和使用说明
    IOS常用设计模式之委托模式
  • 原文地址:https://www.cnblogs.com/helloworld2019/p/10468041.html
Copyright © 2020-2023  润新知