一坨背包的智障题
Posted shixinyi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一坨背包的智障题相关的知识,希望对你有一定的参考价值。
我觉得黄学长刷的背包应该不会太水吧?!
bzoj1334 Elect
Description
Input
Output
Sample Input
1 3 2 4
Sample Output
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
111111
000000
001100
Sample Output
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
5 3 7
Sample Output
HINT
0<=beginlevel<=maxlevel
//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 小熊分糖
糖罐里有N颗糖,小熊BIBO要挑出m颗来给两只小兔子,剩下的留着自己吃。 对于这n颗糖中的每一颗,这两只小兔子都有各自的喜欢程度Ai和Bi。小熊BIBO想让挑出来这m颗糖的“Ai和”与“Bi和”的差尽量小,在满足“Ai和”与“Bi和”的差最小的情况下呢,要让“Ai和”与“Bi和”的和尽量大。 小熊BIBO可不擅长算数,所以想请你告诉她,如果选m颗糖,“Ai和”与“Bi和”的最小差是多少,还有在满足这个最小差的情况下,最大和是多少。
输入格式
接下来有n行,每行两个数字Ai和Bi,代表第i颗糖的Ai值和Bi值。
输出格式
第一行是这m颗糖的“Ai和”与“Bi和”的差的最小值。
第二行是在满足第一行答案的选糖所有方案中,“Ai和”与“Bi和”的最大值。
请注意,本题中提及的“差”,均是指两数相减的绝对值,即 |A-B|。
测试样例1
输入
4 2
1 2
2 3
4 1
6 2
输出
2
10
解释:挑出的是第二颗和第三颗糖。
备注
对于30%的数据,0<n<=50,
对于100%的数据, 0<n<=200, 0<m<=20, 0<=Ai,Bi<=20.
输入数据均为整数。
//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
1 4
2 6
3 12
2 7
输入说明:
贝茜收集了4块宝石,她能忍受重量最大为6的手镯。
Sample Output
输出说明:
贝茜把除了第二块宝石的其余所有宝石都镶上手镯,这样她能增加
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; }
以上是关于一坨背包的智障题的主要内容,如果未能解决你的问题,请参考以下文章