• 【动态规划】【归并】Vijos P1412 多人背包


    题目链接:

      https://vijos.org/p/1412

    题目大意:

      求01背包的前K优解,要求必须装满(1<=K<=50 0<=V<=5000 1<=N<=200)

    题目思路:

      【动态规划】

      f[j][k]表示花费为j的第k优解。一开始全部赋为负值,f[0][1]=0,通过k优解转移得到新的k优解,和原来的比较后更新k优解。合并的过程用归并。

     1 //
     2 //by coolxxx
     3 ////<bits/stdc++.h>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<string>
     7 #include<iomanip>
     8 #include<memory.h>
     9 #include<time.h>
    10 #include<stdio.h>
    11 #include<stdlib.h>
    12 #include<string.h>
    13 //#include<stdbool.h>
    14 #include<math.h>
    15 #define min(a,b) ((a)<(b)?(a):(b))
    16 #define max(a,b) ((a)>(b)?(a):(b))
    17 #define abs(a) ((a)>0?(a):(-(a)))
    18 #define lowbit(a) (a&(-a))
    19 #define sqr(a) ((a)*(a))
    20 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))
    21 #define mem(a,b) memset(a,b,sizeof(a))
    22 #define eps (1e-8)
    23 #define J 10
    24 #define MAX 0x7f7f7f7f
    25 #define PI 3.14159265358979323
    26 #define N 204
    27 #define M 5004
    28 #define K 54
    29 using namespace std;
    30 typedef long long LL;
    31 int cas,cass;
    32 int n,m,lll,ans;
    33 int v[N],c[N],t[K<<1];
    34 int f[M][K];
    35 void merge(int a[],int b[],int c)
    36 {
    37     int i,j,k;
    38     for(i=1,j=1,k=0;i+j<=cas+1;)
    39     {
    40         if(a[i]>b[j]+c)t[++k]=a[i++];
    41         else t[++k]=b[j++]+c;
    42     }
    43     while(i<=cas)t[++k]=a[i++];
    44     while(j<=cas)t[++k]=b[j++]+c;
    45     for(i=1;i<=cas;i++)a[i]=t[i];
    46 }
    47 int main()
    48 {
    49     #ifndef ONLINE_JUDGE
    50 //    freopen("1.txt","r",stdin);
    51 //    freopen("2.txt","w",stdout);
    52     #endif
    53     int i,j;
    54 //    for(scanf("%d",&cas);cas;cas--)
    55 //    for(scanf("%d",&cas),cass=1;cass<=cas;cass++)
    56 //    while(~scanf("%s",s))
    57     while(~scanf("%d",&cas))
    58     {
    59         mem(f,-0x7f);mem(t,-0x7f);ans=0;
    60         scanf("%d%d",&m,&n);
    61         for(i=1;i<=n;i++)
    62         {
    63             scanf("%d%d",&v[i],&c[i]);
    64         }
    65         f[0][1]=0;
    66         for(i=1;i<=n;i++)
    67         {
    68             for(j=m;j>=v[i];j--)
    69             {
    70                 merge(f[j],f[j-v[i]],c[i]);
    71             }
    72         }
    73         for(i=1;i<=cas && f[m][i]>0;i++)ans+=f[m][i];
    74         printf("%d
    ",ans);
    75     }
    76     return 0;
    77 }
    78 /*
    79 //
    80 
    81 //
    82 */
    View Code
  • 相关阅读:
    Java字节流Stream的使用,创建方法
    Java中字节流和字符流复制文件
    Java中的IO流,Input和Output的用法,字节流和字符流的区别
    Java中String的常用方法总结
    java中File类的常用方法总结
    Java中递归的优缺点,Java写一个递归遍历目录下面的所有文件包括子文件夹里边的文件。
    Mysql 5.5从零开始学阅读笔记
    RDS for MySQL有哪些限制
    mysql查看建表语句命令
    MYSQL查看当前正在使用的数据库命令
  • 原文地址:https://www.cnblogs.com/Coolxxx/p/5774036.html
Copyright © 2020-2023  润新知