zoukankan      html  css  js  c++  java
  • HDOJ4526 威威猫系列故事——拼车记

    威威猫系列故事——拼车记

    Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
    Total Submission(s): 938    Accepted Submission(s): 284


    Problem Description
      话说威威猫有一次去参加比赛,虽然学校离比赛地点不太远,但威威猫还是想坐出租车去。大学城的出租车总是比较另类,有“拼车”一说,也就是说,你一个人坐车去,还是一堆人一起,总共需要支付的钱是一样的(每辆出租上除司机外最多坐下4个人)。刚好那天同校的一群Acmer在校门口扎堆了,大家果断决定拼车去赛场。
      问题来了,一辆又一辆的出租车经过,但里面要么坐满了乘客,要么只剩下一两个座位,众Acmer都觉得坐上去太亏了,威威猫也是这么想的。
      假设N名Acmer准备拼车,此时为0时刻,从校门到目的地需要支付给出租车师傅D元(按车次算,不管里面坐了多少Acmer),假如S分钟后恰能赶上比赛,那么S分钟后经过校门口的出租车自然可以忽略不计了。现在给出在这S分钟当中经过校门的所有的K辆出租车先后到达校门口的时间Ti 及里面剩余的座位Zi (1 <= Zi <= 4),Acmer可以选择上车几个人(不能超过),当然,也可以选择上0个人,那就是不坐这辆车。
      俗话说,时间就是金钱,这里威威猫把每个Acmer在校门等待出租车的分钟数等同于花了相同多的钱(例如威威猫等待了20分钟,那相当于他额外花了20元钱)。
      在保证所有Acmer都能在比赛开始前到达比赛地点的情况下,聪明的你能计算出他们最少需要花多少元钱么?
     
    Input
    输入第一行为T,表示有T组测试数据。每组数据以四个整数N , K , D , S开始,具体含义参见题目描述,接着K行,表示第i辆出租车在第Ti分钟到达校门,其空余的座位数为Zi(时间按照先后顺序)。
    [Technical Specification]
    T <= 50
    N <= 100
    K <= 100
    D <= 100
    S <= 100
    1 <= Zi <= 4
    1<= T(i) <= T(i+1) <= S
     
    Output
    对于每组测试数据,输出占一行,如果他们所有人能在比赛前到达比赛地点,则输出一个整数,代表他们最少需要花的钱(单位:元),否则请输出“impossible”。
     
    Sample Input
    1 2 2 10 5 1 1 2 2
     
    Sample Output
    14
     
    Source
     
    Recommend
    liuyiding
     
    代码一:------AC
    没有用二进制打包优化,直接转化为0-1背包做的,数据量小,没有超时,直接AC 。。。。。
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 
     5 using namespace std;
     6 
     7 int n, k, d, s;
     8 int t[110], num[110], dp[110];
     9 
    10 int min(int a1, int a2)
    11 {
    12     return a1 < a2 ? a1 : a2;
    13 }
    14 
    15 int main()
    16 {
    17     int T;
    18     scanf("%d", &T);
    19     while(T--)
    20     {
    21         scanf("%d%d%d%d", &n, &k, &d, &s);
    22         for(int i = 1; i <= k; ++i)
    23             scanf("%d%d", &t[i], &num[i]);
    24         for(int i = 1; i <= n; ++i) 
    25             dp[i] = 0x3fffffff;
    26         dp[0] = 0;
    27         
    28         for(int i = 1; i <= k; ++i)
    29         {
    30             for(int j = n; j >= 0; --j)
    31             {
    32                 for(int r = num[i]; r > 0; --r)
    33                 {
    34                     dp[j] = min(dp[j], dp[j-r] + r*t[i] + d);
    35                 }
    36             }
    37         }
    38         if(dp[n] != 0x3fffffff) 
    39             printf("%d\n", dp[n]);
    40         else 
    41             printf("impossible\n");
    42     }
    43     return 0;
    44 }

    代码二:-----------WA

    我想用二进制打包做,不知道为啥一直 WA,求解释。。。。。。。????。。。。
    wrong answer 代码如下:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 
     5 using namespace std;
     6 
     7 int n, k, d, s;
     8 int t[110], num[110], dp[110];
     9 
    10 int min(int a1, int a2)
    11 {
    12     return a1 < a2 ? a1 : a2;
    13 }
    14 
    15 int main()
    16 {
    17     int T;
    18     scanf("%d", &T);
    19     while(T--)
    20     {
    21         scanf("%d%d%d%d", &n, &k, &d, &s);
    22         for(int i = 1; i <= k; ++i)
    23             scanf("%d%d", &t[i], &num[i]);
    24         for(int i = 1; i <= n; ++i) 
    25             dp[i] = 0x3fffffff;
    26         dp[0] = 0;
    27         
    28         for(int i = 1; i <= k; ++i)
    29         {
    30             if(num[i] >= n)  //转化为完全背包 
    31             {
    32                 for(int j = 0; j <= n; ++j)
    33                 {
    34                     for(int k = 0; k <= j; ++k)
    35                         dp[j] = min(dp[j], dp[j-k] + k*t[i] + d);
    36                 }
    37             }
    38             else     // 转化为 0-1 背包,利用二进制打包的思想 
    39             {
    40                 int tmp = 1;
    41                 while(num[i] >= tmp)
    42                 {
    43                     for(int j = n; j >= 0; --j)
    44                         dp[j] = min(dp[j], dp[j-tmp] + tmp*t[i] + d);
    45                     num[i] -= tmp;
    46                     tmp <<= 1;
    47                 }
    48                 for(int j = n; j >= 0; --j)
    49                     dp[j] = min(dp[j], dp[j-num[i]] + num[i]*t[i] + d);
    50             }
    51         }
    52         if(dp[n] != 0x3fffffff) 
    53             printf("%d\n", dp[n]);
    54         else 
    55             printf("impossible\n");
    56     }
    57     return 0;
    58 }
  • 相关阅读:
    贝叶斯公式推导
    三种常量池
    SpringCloud使用Feign实现服务间通信
    springCloud配置本地配中心SpringCloudConfig
    SpringApplication执行流程
    调用shutdown.sh后出现could not contact localhost8005 tomcat may not be running报错问题
    TCP协议详解
    web.xml配置说明
    第一份offer
    博客CSS
  • 原文地址:https://www.cnblogs.com/dongsheng/p/3116043.html
Copyright © 2011-2022 走看看