一坨背包的智障题

Posted shixinyi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一坨背包的智障题相关的知识,希望对你有一定的参考价值。

我觉得黄学长刷的背包应该不会太水吧?!

bzoj1334 Elect

Description

N个政党要组成一个联合内阁,每个党都有自己的席位数. 现在希望你找出一种方案,你选中的党的席位数要大于总数的一半,并且联合内阁的席位数越多越好. 对于一个联合内阁,如果某个政党退出后,其它党的席位仍大于总数的一半,则这个政党被称为是多余的,这是不允许的.

Input

第一行给出有多少个政党.其值小于等于300 下面给出每个政党的席位数.总席位数小于等于 100000

Output

你的组阁方案中最多能占多少个席位.

Sample Input

4
1 3 2 4

Sample Output

7

HINT

选择第二个政党和第四个

//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=1e5+10,INF=1e6;
int n,a[310],tot;
int f[maxn];
 
int aa;char cc;
int read() {
    aa=0;cc=getchar();
    while(cc<\'0\'||cc>\'9\') cc=getchar();
    while(cc>=\'0\'&&cc<=\'9\') aa=aa*10+cc-\'0\',cc=getchar();
    return aa;
}
 
bool cmp(const int x,const int y) {return x>y;}
 
int main() {
    n=read();
    for(int i=1;i<=n;++i)a[i]=read(),tot+=a[i];
    sort(a+1,a+n+1,cmp);
    memset(f,-1,sizeof(f));
    f[0]=INF;tot/=2;
    for(int i=1;i<=n;++i) {
        for(int j=tot;j>=0;--j) if(f[j]!=-1) f[j+a[i]]=max(f[j+a[i]],min(f[j],a[i]));
    }
    for(int i=tot*2+1;i>tot;--i) if(i-f[i]<=tot) {
        printf("%d",i);
        return 0;
    }
    return 0;
}

  

bzoj1296 粉刷匠

Description

windy有 N 条木板需要被粉刷。 每条木板被分为 M 个格子。 每个格子要被刷成红色或蓝色。 windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色。 每个格子最多只能被粉刷一次。 如果windy只能粉刷 T 次,他最多能正确粉刷多少格子? 一个格子如果未被粉刷或者被粉刷错颜色,就算错误粉刷。

Input

输入文件paint.in第一行包含三个整数,N M T。 接下来有N行,每行一个长度为M的字符串,\'0\'表示红色,\'1\'表示蓝色。

Output

输出文件paint.out包含一个整数,最多能正确粉刷的格子数。

Sample Input

3 6 3
111111
000000
001100

Sample Output

16

HINT

30%的数据,满足 1 <= N,M <= 10 ; 0 <= T <= 100 。 100%的数据,满足 1 <= N,M <= 50 ; 0 <= T <= 2500 。

竟然是SCOI的题。。。

//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=50+5;
int n,m,tot,cl[maxn],dp[maxn*maxn],f[maxn][maxn];
 
int main() {
    scanf("%d%d%d",&n,&m,&tot); int x;
    for(int i=1;i<=n;++i) {
        for(int j=1;j<=m;++j) scanf("%1d",&cl[j]),cl[j]+=cl[j-1];
        memset(f,0,sizeof(f));
        for(int j=1;j<=m;++j) for(int k=1;k<=j;++k) {
            x=cl[j]-cl[k-1];x=max(x,j-k+1-x);
            for(int t=1;t<=min(m,tot);++t) f[j][t]=max(f[j][t],f[k-1][t-1]+x);
        }
        for(int j=tot;j;--j) for(int k=1;k<=min(m,tot)&&k<=j;++k) dp[j]=max(dp[j],dp[j-k]+f[m][k]); 
    }
    printf("%d",dp[tot]);
    return 0;
}

  

bzoj2748 音量调节

Description

一个吉他手准备参加一场演出。他不喜欢在演出时始终使用同一个音量,所以他决定每一首歌之前他都要改变一次音量。在演出开始之前,他已经做好了一个列表,里面写着在每首歌开始之前他想要改变的音量是多少。每一次改变音量,他可以选择调高也可以调低。
音量用一个整数描述。输入文件中给定整数beginLevel,代表吉他刚开始的音量,以及整数maxLevel,代表吉他的最大音量。音量不能小于0也不能大于maxLevel。输入文件中还给定了n个整数c1,c2,c3…..cn,表示在第i首歌开始之前吉他手想要改变的音量是多少。
吉他手想以最大的音量演奏最后一首歌,你的任务是找到这个最大音量是多少。

Input

第一行依次为三个整数:n, beginLevel, maxlevel。
第二行依次为n个整数:c1,c2,c3…..cn。

Output

输出演奏最后一首歌的最大音量。如果吉他手无法避免音量低于0或者高于maxLevel,输出-1。

Sample Input

3 5 10
5 3 7

Sample Output

10

HINT

1<=N<=50,1<=Ci<=Maxlevel 1<=maxlevel<=1000

0<=beginlevel<=maxlevel
 
这竟然是道HAOI的题。
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=50+5,maxnum=1000+10;
int n,x,d;
bool f[maxn][maxnum];
 
int aa,ff;char cc;
int read() {
    aa=0;cc=getchar();ff=1;
    while(cc<\'0\'||cc>\'9\') {
        if(cc==\'-\') ff=-1;
        cc=getchar();
    }
    while(cc>=\'0\'&&cc<=\'9\') aa=aa*10+cc-\'0\',cc=getchar();
    return aa*ff;
}
 
int main() {
    n=read();x=read();d=read();
    f[0][x]=1;
    for(int i=1;i<=n;++i) {
        x=read();
        for(int j=0;j<=d;++j) if(f[i-1][j]) {
            if(j+x<=d) f[i][j+x]=1;
            if(j-x>=0) f[i][j-x]=1;
        }
    }
    for(int j=d;j>=0;--j) if(f[n][j]) {
        printf("%d",j);return 0;
    }
    printf("-1");
    return 0;
}

  

 

tyvj1608 小熊分糖

晴朗的上午,小熊BIBO抱着一罐糖,出去找好朋友,两只小兔子。从小熊家出来,穿过小树林,在一个有向日葵的路口向右拐,这就是小兔子家了。小熊BIBO见到好朋友,开心的不得了,BIBO要做的第一件事,是分糖,因为大熊说过,好东西是不可以独享的。
糖罐里有N颗糖,小熊BIBO要挑出m颗来给两只小兔子,剩下的留着自己吃。 对于这n颗糖中的每一颗,这两只小兔子都有各自的喜欢程度Ai和Bi。小熊BIBO想让挑出来这m颗糖的“Ai和”与“Bi和”的差尽量小,在满足“Ai和”与“Bi和”的差最小的情况下呢,要让“Ai和”与“Bi和”的和尽量大。 小熊BIBO可不擅长算数,所以想请你告诉她,如果选m颗糖,“Ai和”与“Bi和”的最小差是多少,还有在满足这个最小差的情况下,最大和是多少。

输入格式

输入文件的第一行,有两个数字,n和m,代表小熊BIBO要从n颗糖中挑出m颗。
接下来有n行,每行两个数字Ai和Bi,代表第i颗糖的Ai值和Bi值。

输出格式

输出应该包含两行数字。
第一行是这m颗糖的“Ai和”与“Bi和”的差的最小值。
第二行是在满足第一行答案的选糖所有方案中,“Ai和”与“Bi和”的最大值。

请注意,本题中提及的“差”,均是指两数相减的绝对值,即 |A-B|。

测试样例1

输入

4 2 
1 2 
2 3 
4 1 
6 2

输出


10 

解释:挑出的是第二颗和第三颗糖。

备注

对于10%的数据, 0<n<=5,
对于30%的数据,0<n<=50,
对于100%的数据, 0<n<=200, 0<m<=20, 0<=Ai,Bi<=20.
输入数据均为整数。
 
 
我也是醉了。从昨年二月份开始就全是PE。
我也是。。。难受,气死。
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=200+10,maxm=20+5;
int n,m,a[maxn],b[maxn],dp[maxn][maxm][2*maxn];

int aa,ff;char cc;
int read() {
	aa=0;cc=getchar();ff=1;
	while(cc<\'0\'||cc>\'9\') {
		if(cc==\'-\') ff=-1;
		cc=getchar();
	}
	while(cc>=\'0\'&&cc<=\'9\') aa=aa*10+cc-\'0\',cc=getchar();
	return aa*ff;
}

int main() {
	n=read();m=read(); memset(dp,-1,sizeof(dp));dp[0][0][200]=0;
	for(int i=1;i<=n;++i) a[i]=read(),b[i]=read();
	for(int i=1;i<=n;++i) for(int j=0;j<=m;++j) for(int k=0;k<=400;++k) {
		if(j&&dp[i-1][j-1][k]!=-1)
			dp[i][j][k+a[i]-b[i]]=max(dp[i][j][k+a[i]-b[i]],dp[i-1][j-1][k]+a[i]+b[i]);
		dp[i][j][k]=max(dp[i][j][k],dp[i-1][j][k]);
	}
	for(int i=0;i<=200;++i) if(dp[n][m][200-i]!=-1||dp[n][m][200+i]!=-1) {
		printf("%d\\n%d",i,max(dp[n][m][200-i],dp[n][m][200+i]));
		return 0;
	}
	return 0;
}
/*
4 2
1 2
2 3
4 1
6 2
*/

  

bzoj1625 宝石手镯

Description

贝茜在珠宝店闲逛时,买到了一个中意的手镯。很自然地,她想从她收集的 N(1 <= N <= 3,402)块宝石中选出最好的那些镶在手镯上。对于第i块宝石,它的重量为W_i(1 <= W_i <= 400),并且贝茜知道它在镶上手镯后能为自己增加的魅力值D_i(1 <= D_i <= 100)。由于贝茜只能忍受重量不超过M(1 <= M <= 12,880)的手镯,她可能无法把所有喜欢的宝石都镶上。 于是贝茜找到了你,告诉了你她所有宝石的属性以及她能忍受的重量,希望你能帮她计算一下,按照最合理的方案镶嵌宝石的话,她的魅力值最多能增加多少。

Input

* 第1行: 2个用空格隔开的整数:N 和 M

* 第2..N+1行: 第i+1行为2个用空格隔开的整数:W_i、D_i,分别为第i块宝石 的重量与能为贝茜增加的魅力值

Output

* 第1行: 输出1个整数,表示按照镶嵌要求,贝茜最多能增加的魅力值

Sample Input

4 6
1 4
2 6
3 12
2 7

输入说明:

贝茜收集了4块宝石,她能忍受重量最大为6的手镯。

Sample Output

23

输出说明:

贝茜把除了第二块宝石的其余所有宝石都镶上手镯,这样她能增加
4+12+7=23的魅力值,并且所有宝石的重量为1+2+3 <= 6,同样符合要求。
 
裸得不能再裸了。
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=3402+10,maxm=12880+10;
int n,m,dp[maxm],w[maxn],v[maxn];

int main() {
	cin>>n>>m;
	for(int i=1;i<=n;++i) cin>>w[i]>>v[i];
	for(int i=1;i<=n;++i) for(int j=m;j>=w[i];--j) dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
	printf("%d",dp[m]);
	return 0;
}

  

以上是关于一坨背包的智障题的主要内容,如果未能解决你的问题,请参考以下文章

动态规划_01背包_完全背包_多重背包_分组背包

算法刷题总结

算法刷题总结

算法刷题总结

bmzctf 刷题记录 zonghe

P2347 砝码称重 & P1474 货币系统 Money Systems