• Hdu-6249 2017CCPC-Final G.Alice’s Stamps 动态规划


    题面

    题意:给你n个集合,每个集合有L到R这些种类的邮票,让你选择其中的K个集合,使得最后选择的邮票种类尽可能多,N,L,R都<=2000

    题解:容易乱想到网络流,可是再细想一下就会发现处理不了这种模型的

            然后看数据范围,想到dp,定义状态f[i][j]表示前i个集合选j个的最多种类,

            我们发现这需要N^3,因为每次除了枚举i,j还要枚举一个q,来记录新的一个集合是从上次的哪一个集合拓展覆盖来的

            苦思不得其解,看全场都a了,终于在最后1h改了状态(打的当然是重现赛)

           我们发现L,R也只有2000啊,刚刚那种定义如果可行,L,R不就离散一下,没必要说这个了啊

           所以又定义f[i][j],表示1-i的种类,用了j个集合的最好方案,对于每个位置i,我们先预处理up数组,覆盖i的区间最右能延伸到哪里

           转移就是f[i][j+1]=max(f[i-1][j+1]f,[i][j+1])    if (up[i]) f[up[i]][j+1]=max (f[up[i]][j+1],f[i-1][j]+len);  len 就是等于up[i]-i+1;

         

     1 #include<bits/stdc++.h>
     2 #define N 2005 
     3 using namespace std;
     4 int f[N][N],up[N],T,t=1,n,m,k;
     5 int main()
     6 {
     7     cin>>T;
     8     while (T--)
     9     {
    10         scanf("%d%d%d",&n,&m,&k);
    11         memset(up,0,sizeof up);
    12         memset(f,0,sizeof f);
    13         for(int i=1,x,y;i<=m;i++)
    14         {
    15             scanf("%d%d",&x,&y);
    16             for(int j=x;j<=y;j++) up[j]=max(up[j],y);
    17         }
    18         for(int i=1;i<=n;i++)
    19             for(int j=0;j<k;j++)
    20             {
    21                 f[i][j+1]=max(f[i][j+1],f[i-1][j+1]);
    22                 if (up[i]) f[up[i]][j+1]=max(f[up[i]][j+1],f[i-1][j]+up[i]-i+1);
    23             }
    24         printf("Case #%d: %d
    ",t++,f[n][k]);
    25     }
    26     return 0;
    27 }
  • 相关阅读:
    阅读《最后期限》有感(1)
    软件工程课程改进建议
    团队开发第二次冲刺第七天
    返回一个二维整数数组中最大联通子数组的和
    大道至简阅读笔记三
    大道至简阅读笔记二
    大道至简阅读笔记一
    团队冲刺阶段二第十次站立会议
    对软工课程的意见建议
    团队冲刺阶段二第九次站立会议
  • 原文地址:https://www.cnblogs.com/qywhy/p/9764631.html
Copyright © 2020-2023  润新知