• 动态规划练习题


    RQNOJ 496

    /*
      dp记录路径的问题
      f[i][j]表示用前j个花瓶盛放前i朵花的最大值
    */
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define N 110
    #define INF 1000000000
    using namespace std;
    int a[N][N],f[N][N],q[N],n,m;
    int main()
    {
        memset(f,-127/3,sizeof(f));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
          for(int j=1;j<=m;j++)
            scanf("%d",&a[i][j]);
        f[0][0]=0;
        for(int i=1;i<=n;i++)
          for(int j=i;j<=m;j++)
            for(int k=i-1;k<j;k++)
              f[i][j]=max(f[i-1][k]+a[i][j],f[i][j]);
        int ans=-INF,pos;
        for(int i=n;i<=m;i++)
          if(f[n][i]>ans)
          {
              ans=f[n][i];pos=i;
          }
        printf("%d
    ",ans);
        q[n]=pos;
        int x=n;
        while(x--)
        {
            for(int i=1;i<pos;i++)
              if(f[x][i]==ans-a[x+1][pos])
              {
                  q[x]=i;ans-=a[x+1][pos];pos=i;
                  break;
              }
        }
        for(int i=1;i<=n;i++)printf("%d ",q[i]);
        return 0;
    }

    tyvj 1313

    /*
      朴素的动规很好想,f[i]表示选前i个且第i个必选的最小值。f[i]=f[j]+a[i]
      因为可以选的j来自一段固定长度的区间,并且我们每次要选最小值,所以可以用单调队列优化。
    */
    #include<iostream>  
    #include<cstring>  
    #include<cstdio>  
    #define N 1000010
    #define inf 2100000000   
    using namespace std;  
    int n,m,head,tail,Min;  
    int q[N],a[N],f[N];  
    int main()
    {  
        scanf("%d%d",&n,&m);  
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);  
        for (int i=1;i<=n;i++)
        {  
            while (q[head]<i-m&&head<=tail) head++;  
            f[i]=a[i]+f[q[head]];  
            while (f[q[tail]]>f[i]&&head<=tail) tail--;  
            q[++tail]=i;  
        }  
        Min=inf;  
        for (int i=n-m+1;i<=n;++i)  
          Min=min(Min,f[i]);  
        printf("%d
    ",Min);  
    }

    洛谷 1650

    /*
      虽说是dp,但总觉得有些贪心的思想在里面
      因为我们尽量要把齐王的跑得慢的马比下去,而且要尽量用田忌的马中比较慢的。
      所以先排一遍序,然后当当前田忌的马慢时,换下一匹,如果一样快,可以换下一匹,也可以这样比,如果快,就比。
    */
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #define N 2016
    #define inf 100000000
    using namespace std;
    int a[N],b[N],f[N][N],n,ans=-inf;
    int dfs(int x,int y)
    {
        if(f[x][y]!=-1)return f[x][y];
        if(x>n)return 0;
        if(a[x]<b[y])f[x][y]=dfs(x+1,y)-200;
        else if(a[x]==b[y])
          f[x][y]=max(dfs(x+1,y)-200,dfs(x+1,y+1));
        else f[x][y]=dfs(x+1,y+1)+200;
        return f[x][y];
    }
    int main()
    {
        freopen("jh.in","r",stdin);
        memset(f,-1,sizeof(f));
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
          scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
          scanf("%d",&b[i]);
        sort(a+1,a+n+1);sort(b+1,b+n+1);
        printf("%d",dfs(1,1));
        return 0;
    }

    洛谷 1594

    /*
      80分,有两个数据爆了double了,没有过
      记忆化搜索,很好理解。 
      f[x][y]表示通过前x辆车,且第x辆车所属车队以y开头的最少时间 
    */
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define N 1010
    using namespace std;
    int w[N],n,zz;double f[N][N],t[N],s,ans=100000000.0;
    double query(int x,int y)//数据较弱,懒得写rmq了 
    {
        double maxn=0;
        for(int i=x;i<=y;i++)
          maxn=max(maxn,t[i]);
        return maxn;
    }
    double dfs(int x,int y)
    {
        if(f[x][y]!=-1.0)return f[x][y];
        if(x>n)return 0;
        if(w[x+1]-w[y-1]<=zz&&x<n)
          f[x][y]=min(dfs(x+1,y),dfs(x+1,x+1)+query(y,x));
        else
          f[x][y]=dfs(x+1,x+1)+query(y,x);
        return f[x][y];
    }
    int main()
    {
        scanf("%d%lf%d",&zz,&s,&n);
        for(int i=0;i<=n;i++)
          for(int j=0;j<=n;j++)
            f[i][j]=-1.0;
        for(int i=1;i<=n;i++)
        {
            double v;scanf("%d%lf",&w[i],&v);
            t[i]=s*60/v;w[i]+=w[i-1];
        }
        printf("%.1lf",dfs(1,1));
        return 0;
    }
  • 相关阅读:
    win7下cygwin命令行颜色和中文乱码解决
    maven mirror
    maven命令
    dubbo获取错误ip
    eclipse netbeans 代码模板
    windows下配置Groovy
    c++ 载入内存中dll ,以及内存注入
    表达式求值的 计算器
    vc 编译器的一些精典报错
    内联汇编实现 memcpy 和 memset
  • 原文地址:https://www.cnblogs.com/harden/p/6044853.html
Copyright © 2020-2023  润新知