zoukankan      html  css  js  c++  java
  • JZYZOJ1445 [noip2014day1-T3]飞扬的小鸟 动态规划 完全背包

    http://172.20.6.3/Problem_Show.asp?id=1445

    很容易看出来动态规划的本质,但是之前写的时候被卡了一下(不止一下),还是写一下题解。

    直接暴力O(n*m^2)大概是70分,比较划算。

    100分需要对上升下降方式找规律然后优化到O(nm);

    可以看出,70分算法有很多时间浪费在没必要的上升计算上,为了减少上升计算,我们可以在预处理后把上升计算变为只有一次。

    把下降的放在最后处理。

    观察可以发现f[i][x]的赋值只可能来自于下面升上来的,其实本质就是一个有一点特殊的完全背包,然后背包处理就可以了。(不一定要像我那样写的,我觉得其实有更好看更容易懂的写法)

    最后再处理一个下降的方案比较后赋值。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<iostream>
     6 using namespace std;
     7 const int maxn=10010;
     8 int n,m,k;
     9 int a[maxn][2]={};
    10 int f[maxn][1010]={},g[1010]={};
    11 int d[maxn]={};
    12 struct nod{
    13     int p,l,h;
    14 }e[maxn];
    15 bool mmp(nod aa,nod bb){
    16     return aa.p<bb.p;
    17 }
    18 int main(){
    19     //freopen("wtf.in","r",stdin);
    20     scanf("%d%d%d",&n,&m,&k);
    21     for(int i=1;i<=n;i++){
    22         scanf("%d%d",&a[i][0],&a[i][1]);
    23     }
    24     for(int i=1;i<=k;i++){
    25         scanf("%d%d%d",&e[i].p,&e[i].l,&e[i].h);
    26     }sort(e+1,e+1+k,mmp);
    27     for(int i=1;i<=k;i++){
    28         d[e[i].p]=i;
    29     }
    30     memset(f,63,sizeof(f));
    31     int ans=f[1][1],cnt=f[1][1];
    32     for(int i=1;i<=m;i++)f[0][i]=0;
    33     int w=0;
    34     for(int i=0;i<n;i++){
    35         int mi=1,ma=m;
    36         if(d[i]){
    37             mi=e[d[i]].l+1,ma=e[d[i]].h-1;
    38         }
    39         int ff=0;
    40         memset(g,63,sizeof(g));
    41         for(int j=mi;j<=ma;j++){
    42             g[j]=f[i][j];
    43             if(f[i][j]!=cnt)ff=1;
    44         }
    45         for(int j=1;j<=m;j++){
    46             int x=min(m,a[i+1][0]+j);
    47             g[x]=min(g[x],g[j]+1);
    48         }
    49         for(int j=1;j<=m;j++){
    50             int x=min(m,a[i+1][0]+j);
    51             f[i+1][x]=min(f[i+1][x],g[j]+1);
    52         }
    53         for(int j=mi;j<=ma;j++){
    54             if(j-a[i+1][1]>0) f[i+1][j-a[i+1][1]]=min(f[i+1][j-a[i+1][1]],f[i][j]); 
    55         }
    56         if(!ff){
    57             printf("0
    %d
    ",w);
    58             return 0;
    59         }
    60         if(d[i])w++;
    61     }
    62     for(int i=1;i<=m;i++){
    63         ans=min(ans,f[n][i]);
    64     }
    65     printf("1
    %d
    ",ans);
    66     return 0;
    67 }
    View Code
  • 相关阅读:
    三级连动的下拉框(数据库版)吐血推荐
    行排菜单
    用AJAX制作天气预
    XmlHttp实战学习中....
    ASP+JS三级连动下拉框
    ASP连接11种数据库语法总结
    oa数据库设计
    RSS PUBData 把正常时间函数转成rss2.0的标准
    浮点数的表示和基本运算
    C#4.0新特性:可选参数,命名参数,Dynamic
  • 原文地址:https://www.cnblogs.com/137shoebills/p/7798231.html
Copyright © 2011-2022 走看看