• Codeforces 988F Rain and Umbrellas 【dp】


    这题的关键在于想到怎么dp,及怎样去描述一个状态。

    首先想到dp[i]表示到达i位置的最小疲劳值,但发现这样不太对,因为这样的话不好转移(因为转移的时候我们需要知道拿着哪把伞走过一格);因此想到dp[i][j]表示走到i点拿着j雨伞的最小疲劳值。这样的话怎么转移呢

    如果这个格子上有j雨伞,那说明j雨伞就是在i这个位置上拿的 dp[i][j] = min( dp[i][j],dp[i-1][k]+id[k] ) 【k=0-m】 //j=0时代表不拿伞, id[i]代表i雨伞的重量

    如果没有j雨伞,那说明在到达i点前就拿到j雨伞了 dp[i][j] = dp[i-1][j] + id[j]

    那转移方程写完了,最后考虑边界条件。

    1.在起点

    2.在雨里但j=0

    以上

    ===2018.9.5===

    这次想了一下时间复杂度,乍一看是a*m*m的复杂度会tle。(因为有a*m个状态;然后如果点i上有j这把雨伞的话那要m的代价转移,不然O(1)转移)

    但实际上它的复杂度就是a*m,因为不会每个状态都要m代价转移。(因为只有m把雨伞,最多只有m个状态要花m的代价去转移。)

    所以就过了。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<vector>
     5 #define INF 2100000000
     6 using namespace std;
     7 
     8 int rain[2005],id[2005];//id[i]代表编号为i的雨伞的重量
     9 vector<int> umb[2005];//每个位置上可能有多个雨伞 
    10 int memo[2005][2005];//dp[i][j]代表拿着j雨伞走到i点【此时换完伞准备出发】的最小疲劳值,j=0代表不拿伞
    11 
    12 int main(){
    13     int a,n,m; cin>>a>>n>>m;
    14     for(int i=1;i<=n;i++){
    15         int l,r; cin>>l>>r;
    16         for(int j=l;j<r;j++) rain[j]=1;
    17     }
    18     for(int i=1;i<=a;i++) umb[i].push_back(0);
    19     for(int i=1;i<=m;i++){
    20         int x,p; cin>>x>>p;
    21         umb[x].push_back(i);
    22         id[i]=p;
    23     }
    24     
    25     for(int i=0;i<=a;i++){
    26         for(int j=0;j<=m;j++){
    27             bool contain=false;
    28             for(int k=0;k<umb[i].size();k++){
    29                 if(umb[i][k]==j) contain=true;
    30             }    
    31             
    32             if(rain[i] && j==0) memo[i][j]=INF;//在雨里还没有雨伞
    33             else if(i==0){//在0点时特判
    34                 if( !contain && j!=0 ) memo[i][j]=INF;
    35                 else memo[i][j]=0;
    36                 }
    37             else if(contain){//在i点才拿起编号为j的雨伞
    38                 int cost=INF;
    39                 for(int v=0;v<=m;v++) cost=min(cost,memo[i-1][v]+id[v]);
    40                 memo[i][j]=cost;
    41                 }
    42             else memo[i][j]=min(INF,memo[i-1][j]+id[j]);//到达i点前就拿到j雨伞
    43             
    44         //    cout<<i<<" "<<j<<" "<<memo[i][j]<<endl; 
    45         }    
    46     }
    47     
    48     
    49     int ans=INF;
    50     for(int i=0;i<=m;i++) ans=min(ans,memo[a][i]);
    51 
    52     if(ans==INF) cout<<-1;
    53     else cout<<ans;
    54 
    55     return 0;
    56 }
  • 相关阅读:
    北京西格玛大厦微软社区精英 Visual Studio 2010 技术交流会记录
    2010522 Windows Phone 开发者日
    SharePoint Server 2010 RTM 安装过程(图)
    Windows HPC Server 2008 R2 简体中文版 下载
    转:Community Clips 使用指南
    关于CS0016: Could not write to output file ‘c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files… ‘Access is denied.’ 的解决办法
    岗位职责
    PowerPoint 2010 的广播幻灯片功能尝试了一下,可以用。
    Silverlight 4 五
    Windows Server AppFabric 简体中文 下载地址
  • 原文地址:https://www.cnblogs.com/ZhenghangHu/p/9140320.html
Copyright © 2020-2023  润新知