zoukankan      html  css  js  c++  java
  • 飞扬的小鸟 DP

    飞扬的小鸟 DP

    细节有点恶心的DP,设(f[i][j])表示横坐标为(i)(从(0)开始)高度为(j)时,屏幕点击的最小次数为(f[i][j]),转移便很好写了,这里要注意枚举当前状态时要枚举完所有(j),因为每次转移只向上跳了一次,所以必须枚举完。

    for(int j=1;j<=m+xd[i];++j)
    	if(j-xd[i]>=0)
    		f[i][j]=min(f[i][j-xd[i]]+1, f[i-1][j-xd[i]]+1); // 向上跳
    for(int j=mih[i];j<=mxh[i];++j)
      f[i][j]=min(f[i][j], f[i-1][j+yd[i]]); // 向下落
    

    但是题目还有高度限制,即如果跳到(m)以上,高度仍算(m),所以我们还要对于(m)以上转移一下

    for(int j=m+1;j<=m+xd[i];++j)
    	f[i][m]=min(f[i][m], f[i][j]);
    

    然后还要处理一下非法状态,因为之前枚举了所有状态。

    for(int j=1;j<=mih[i]-1;++j) f[i][j]=INF;
    for(int j=mxh[i]+1;j<=m+xd[i];++j) f[i][j]=INF;
    

    AC Code

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define INF 0x3f3f3f3f
    #define MAXN 10010
    using namespace std;
    inline int read(){
        char ch=getchar();int s=0;
        while(ch<'0'||ch>'9') ch=getchar();
        while(ch>='0'&&ch<='9') s=s*10+(ch^'0'), ch=getchar();
        return s;
    }
    int mxh[MAXN],mih[MAXN];
    int xd[MAXN],yd[MAXN];
    int f[MAXN][2002];
    bool hav[MAXN];
    int n,m,k;
    int main(){
        n=read(),m=read(),k=read();
        for(int i=1;i<=n;++i) mxh[i]=m,mih[i]=1;
        for(int i=1;i<=n;++i) xd[i]=read(),yd[i]=read();
        for(int i=1;i<=k;++i){
            int p=read(),l=read(),h=read();
            hav[p]=1;
            mih[p]=l+1;
            mxh[p]=h-1;
        }
        memset(f, 0x3f, sizeof f);
        for(int i=1;i<=m;++i) f[0][i]=0;
        for(int i=1;i<=n;++i){
            for(int j=1;j<=m+xd[i];++j)
                if(j-xd[i]>=0)
                    f[i][j]=min(f[i][j-xd[i]]+1, f[i-1][j-xd[i]]+1);
            for(int j=m+1;j<=m+xd[i];++j)
                f[i][m]=min(f[i][m], f[i][j]);
            for(int j=mih[i];j<=mxh[i];++j)
                f[i][j]=min(f[i][j], f[i-1][j+yd[i]]);
            for(int j=1;j<=mih[i]-1;++j) f[i][j]=INF;
            for(int j=mxh[i]+1;j<=m+xd[i];++j) f[i][j]=INF;
            //for(int j=mih[i];j<=mxh[i];++j) printf("f[%d][%d]=%d
    ", i, j, f[i][j]);
        }
        int ans=INF;
        for(int j=1;j<=m;++j)
            ans=min(ans, f[n][j]);
        if(ans<INF){
            printf("1
    %d", ans);
            return 0;
        }
        for(int i=n-1;i>=0;--i){
            int tmp=INF;
            for(int j=1;j<=m;++j)
                tmp=min(tmp, f[i][j]);
            if(tmp<INF){
                ans=i;
                break;
            }
        }
        int cnt=0;
        for(int i=0;i<=ans;++i)
            if(hav[i]) ++cnt;
        printf("0
    %d", cnt);
        return 0;
    }
    
  • 相关阅读:
    【C语言】C语言static和extern区别
    【C语言】C语言外部变量和内部变量
    【C语言】C语言局部变量和全局变量
    【C语言】C语言常量和变量
    【C语言】C语言数据类型
    【C语言】C语言标识符
    【C语言】C语言关键字
    【C语言】外部函数和内部函数
    【C语言】C语言函数
    Android 测试 Appium、Robotium、monkey等框架或者工具对比
  • 原文地址:https://www.cnblogs.com/santiego/p/11817418.html
Copyright © 2011-2022 走看看