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 }
  • 相关阅读:
    [BJOI2019] 光线
    C# 从零开始写 SharpDx 应用 笔刷
    BAT 脚本判断当前系统是 x86 还是 x64 系统
    BAT 脚本判断当前系统是 x86 还是 x64 系统
    win2d 通过 CanvasActiveLayer 画出透明度和裁剪
    win2d 通过 CanvasActiveLayer 画出透明度和裁剪
    PowerShell 拿到显卡信息
    PowerShell 拿到显卡信息
    win10 uwp 如何使用DataTemplate
    win10 uwp 如何使用DataTemplate
  • 原文地址:https://www.cnblogs.com/fu3638/p/9126288.html
Copyright © 2011-2022 走看看