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

来源:互联网 发布:上海市人口普查数据 编辑:程序博客网 时间:2024/05/16 23:46
题目链接:

  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优解。合并的过程用归并。

 

////by coolxxx////<bits/stdc++.h>#include<iostream>#include<algorithm>#include<string>#include<iomanip>#include<memory.h>#include<time.h>#include<stdio.h>#include<stdlib.h>#include<string.h>//#include<stdbool.h>#include<math.h>#define min(a,b) ((a)<(b)?(a):(b))#define max(a,b) ((a)>(b)?(a):(b))#define abs(a) ((a)>0?(a):(-(a)))#define lowbit(a) (a&(-a))#define sqr(a) ((a)*(a))#define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))#define mem(a,b) memset(a,b,sizeof(a))#define eps (1e-8)#define J 10#define MAX 0x7f7f7f7f#define PI 3.14159265358979323#define N 204#define M 5004#define K 54using namespace std;typedef long long LL;int cas,cass;int n,m,lll,ans;int v[N],c[N],t[K<<1];int f[M][K];void merge(int a[],int b[],int c){int i,j,k;for(i=1,j=1,k=0;i+j<=cas+1;){if(a[i]>b[j]+c)t[++k]=a[i++];else t[++k]=b[j++]+c;}while(i<=cas)t[++k]=a[i++];while(j<=cas)t[++k]=b[j++]+c;for(i=1;i<=cas;i++)a[i]=t[i];}int main(){#ifndef ONLINE_JUDGE//freopen("1.txt","r",stdin);//freopen("2.txt","w",stdout);#endifint i,j;//for(scanf("%d",&cas);cas;cas--)//for(scanf("%d",&cas),cass=1;cass<=cas;cass++)//while(~scanf("%s",s))while(~scanf("%d",&cas)){mem(f,-0x7f);mem(t,-0x7f);ans=0;scanf("%d%d",&m,&n);for(i=1;i<=n;i++){scanf("%d%d",&v[i],&c[i]);}f[0][1]=0;for(i=1;i<=n;i++){for(j=m;j>=v[i];j--){merge(f[j],f[j-v[i]],c[i]);}}for(i=1;i<=cas && f[m][i]>0;i++)ans+=f[m][i];printf("%d\n",ans);}return 0;}/*////*/


0 0
原创粉丝点击