zoukankan      html  css  js  c++  java
  • poj 2442 优先队列/堆+dp

    题意:

    给出m行,每行n个数,每次从一行中选择一个数,这m个数求和。所有的方案数是n^m,问这些方案中和最小的n个?

    分析:

    这题有点桶排序和滑动窗口的意思,还是挺不错的一道题。因为要最小的n个和,所以可以用优先队列去维护最小的n个和,这n个和是第i行中的元素和前i行的和相加选择的最优的(这又有点动态规划的思想QAQ)。也就是说,前i行得到了n个最小和,那么这n个最小和可以从第i行里各选择n个数求和,一共有n^2种选择,再找出最优的n个值,重复下去。

    具体的实现可以用优先队列去维护,这题划分到堆里了,还是练习一下heap吧,这题的dp思想才是关键!

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=2009;
    const int M=111;
    int a[N],sum[N],q[N],m,n;
    int main()
    {
        int T;scanf("%d",&T);
        while(T--){
            scanf("%d%d",&m,&n);
            for(int i=0;i<n;i++)scanf("%d",&sum[i]);//边界初始化,刚开始只有一行
            m--;
            while(m--){
                for(int i=0;i<n;i++)scanf("%d",&a[i]),q[i]=sum[0]+a[i]; //q是堆,维护n个最优解
                make_heap(q,q+n);
                for(int i=1;i<n;i++)
                for(int j=0;j<n;j++){
                    int t=sum[i]+a[j];
                    if(t<q[0]){
                        pop_heap(q,q+n);
                        q[n-1]=t;
                        push_heap(q,q+n);
                    }
                }
                for(int i=0;i<n;i++)sum[i]=q[i];
            }
            sort(sum,sum+n);
            for(int i=0;i<n;i++)printf("%d%c",sum[i],i==n-1?'
    ':' ');
        }
        return 0;
    }


  • 相关阅读:
    内联函数(inline function)
    被extern "C" 修饰后按照C语言编译
    函数重载-name mangling或mame decoration技术-看看反汇编
    cin、cout
    下载visual studio 环境搭建
    配置共享文件夹
    EFS加密文件系统
    十二、字符串(1)
    十五、文件
    十一、指针
  • 原文地址:https://www.cnblogs.com/01world/p/5762846.html
Copyright © 2011-2022 走看看