zoukankan      html  css  js  c++  java
  • Codeforces 988F Rain and Umbrellas(DP)

    题目链接:http://codeforces.com/contest/988/problem/F

    题目大意:

    有三个整数a,n,m,a是终点坐标,给出n个范围(l,r)表示这块区域下雨,m把伞(p,w)在点p有重量为w的伞。

    小明可以携带任意数量的伞,经过下雨处时必须要撑伞,小明每走一个单位长度消耗的体力与他所携带伞的重量相同,

    求小明从0~a所需消耗的最少体力,若无解则输出-1。

    解题思路:

    第一种解法:

    设dp[i]表示到达i点所需花费的最少体力,rain[i]表示第i段是否下雨(注意是段不是点),ub[j]表示j点放置的伞的重量。

    则当rain[i-1]=false时,dp[i]=dp[i]-1

    rain[i-1]=true是,dp[i]=min{dp[j]+(i-j)*ub[j]},(ub[j]!=1e18且j<=i-1)

    复杂度O(n^2)

    第二种解法:

    设dp数组,

    dp[i][0]表示到达第i段不拿伞最小花费
    dp[i][1]表示到达第i段拿伞最小化费
    dp[i][2]表示到达第i段拿最小重量的伞的最小化费

    然后不想说了,各种递推就是了。。。

    复杂度O(n)

    代码:

    解法一:

     1 #include<bits/stdc++.h>
     2 #define lc(a) (a<<1)
     3 #define rc(a) (a<<1|1)
     4 #define MID(a,b) ((a+b)>>1)
     5 #define fin(name)  freopen(name,"r",stdin)
     6 #define fout(name) freopen(name,"w",stdout)
     7 #define clr(arr,val) memset(arr,val,sizeof(arr))
     8 #define _for(i,start,end) for(int i=start;i<=end;i++)
     9 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
    10 using namespace std;
    11 typedef long long LL;
    12 const int N=2e3+5;
    13 const int INF=0x3f3f3f3f;
    14 const double eps=1e-10;
    15 
    16 LL dp[N],ub[N];
    17 bool rain[N];
    18 
    19 int main(){
    20     FAST_IO;
    21     int a,n,m;
    22     cin>>a>>n>>m;
    23     for(int i=0;i<N;i++){
    24         dp[i]=ub[i]=1e18;
    25     }
    26     for(int i=1;i<=n;i++){
    27         int l,r;
    28         cin>>l>>r;
    29         if(l>r) swap(l,r);
    30         for(int j=l;j<=r-1;j++){
    31             rain[j]=true;
    32         }
    33     }
    34     for(int i=1;i<=m;i++){
    35         LL p,w;
    36         cin>>p>>w;
    37         ub[p]=min(ub[p],w);
    38     }
    39     dp[0]=0;
    40     for(int i=1;i<=a;i++){
    41         if(!rain[i-1]){
    42             dp[i]=dp[i-1];
    43         }
    44         else{
    45             for(int j=i-1;j>=0;j--){
    46                 if(ub[j]!=1e18)
    47                     dp[i]=min(dp[i],dp[j]+(i-j)*ub[j]);
    48             }
    49         }
    50     }
    51     if(dp[a]==1e18)
    52         cout<<-1<<endl;
    53     else
    54         cout<<dp[a]<<endl;
    55     return 0;
    56 }

    解法二:

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<algorithm>
      4 #include<vector>
      5 #include<string>
      6 #include<string.h>
      7 #include<cctype>
      8 #include<math.h>
      9 #include<stdlib.h>
     10 #include<stack>
     11 #include<queue>
     12 #include<set>
     13 #include<map>
     14 #define lc(a) (a<<1)
     15 #define rc(a) (a<<1|1)
     16 #define MID(a,b) ((a+b)>>1)
     17 #define fin(name)  freopen(name,"r",stdin)
     18 #define fout(name) freopen(name,"w",stdout)
     19 #define clr(arr,val) memset(arr,val,sizeof(arr))
     20 #define _for(i,start,end) for(int i=start;i<=end;i++)  
     21 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
     22 using namespace std;
     23 typedef long long LL;
     24 const int N=2e3+5;
     25 const int INF=0x3f3f3f3f;
     26 const double eps=1e-10;
     27 
     28 bool rain[N],flag[N];
     29 LL dp[N][3],ub[N];
     30 //dp[i][0]表示到达第i段不拿伞最小花费
     31 //dp[i][1]表示到达第i段拿伞最小化费
     32 //dp[i][2]表示到达第i段拿最小重量的伞的最小化费 
     33 
     34 int main(){
     35     FAST_IO;
     36     int a,n,m;
     37     cin>>a>>n>>m;
     38     for(int i=0;i<N;i++){
     39         ub[i]=dp[i][0]=dp[i][0]=dp[i][1]=1e18;
     40     }
     41     for(int i=1;i<=n;i++){
     42         int l,r;
     43         if(l>r)
     44             swap(l,r);
     45         cin>>l>>r;
     46         for(int j=l;j<=r-1;j++){
     47             rain[j]=true;
     48         }
     49     }
     50     for(int i=1;i<=m;i++){
     51         LL p,w;
     52         cin>>p>>w;
     53         ub[p]=min(ub[p],w);
     54     }
     55     
     56     if(!rain[0])
     57         dp[0][0]=0;
     58     dp[0][1]=dp[0][2]=ub[0];
     59     LL mmin=ub[0],now=ub[0];
     60     for(int i=1;i<=a-1;i++){
     61         if(ub[i]){
     62             mmin=min(ub[i],mmin);
     63             now=min(ub[i],now);
     64         }
     65         LL t=min(dp[i-1][1]+now,dp[i-1][2]+mmin);
     66         dp[i][1]=t;
     67         if(t==dp[i-1][2]+mmin)
     68             now=mmin;
     69         dp[i][2]=dp[i-1][2]+mmin;
     70             
     71         //下雨 
     72         if(rain[i]){
     73             //有伞 
     74             if(ub[i]){
     75                 dp[i][1]=min(dp[i-1][0]+ub[i],dp[i][1]);
     76                 if(dp[i][1]==dp[i-1][0]+ub[i])
     77                     now=ub[i];    
     78                 if(mmin==ub[i]){
     79                     dp[i][2]=min(dp[i-1][0]+mmin,dp[i][2]);
     80                 }
     81             }
     82         }
     83         //不下雨 
     84         else{
     85             dp[i][0]=min(dp[i-1][0],dp[i-1][1]);
     86             //有伞 
     87              if(ub[i]){
     88                 dp[i][1]=min(dp[i-1][0]+ub[i],dp[i][1]);
     89                 if(dp[i][1]==dp[i-1][0]+ub[i])
     90                     now=ub[i];    
     91                 if(mmin==ub[i]){
     92                     dp[i][2]=min(dp[i-1][0]+mmin,dp[i][2]);
     93                 }
     94             }
     95         }
     96     }
     97     LL ans=min(dp[a-1][0],dp[a-1][1]);
     98     if(ans!=1e18)
     99         cout<<ans<<endl;
    100     else
    101         cout<<-1<<endl;
    102     return 0;
    103 }
  • 相关阅读:
    图形用户界面
    集合
    201671010136 泛型类总结
    异常、断言与日志
    [置顶]201671010131《面向对象程序设计课程学习进度条》
    [置顶]201671010131《面向对象程序设计课程学习进度条》
    201671010131《面向对象程序设计课程学习进度条》
    201671010131《面向对象程序设计课程学习进度条》
    201671010131《面向对象程序设计课程学习进度条》
    201671010131《面向对象程序设计课程学习进度条》
  • 原文地址:https://www.cnblogs.com/fu3638/p/9126288.html
Copyright © 2011-2022 走看看