1、采药(medic.pas/c/cpp)
【问题描述】
辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”
如果你是辰辰,你能完成这个任务吗?
【输入文件】
输入文件medic.in的第一行有两个整数T(1 <= T <= 1000)和M(1<= M <= 100),用一个空格隔开,T代表总共能够用来采药的时间,M代表山洞里的草药的数目。接下来的M行每行包括两个在1到100之间(包括1和100)的整数,分别表示采摘某株草药的时间和这株草药的价值。
【输出文件】
输出文件medic.out包括一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价值。
【样例输入】
70 3
71 100
69 1
1 2
【样例输出】
3
【数据规模】
对于30%的数据,M<= 10;
对于全部的数据,M <= 100。
【思路】经典的01背包 这里给出滚动数组和一维优化两个版本
/*滚动数组*/
#include<cstdio>
int t,m,i,j;
int time[100],v[100];
int f[2][1001];
int main()
{
freopen("medic.in","r",stdin);
freopen("medic.out","w",stdout);
scanf("%d%d",&t,&m);
for (i=0;i<m;i++) scanf("%d%d",&time[i],&v[i]);
for (i=0;i<m;i++)
{
for (j=time[i];j<=t;j++)
if (f[0][j-time[i]]+v[i]>f[1][j]) f[1][j]=f[0][j-time[i]]+v[i];
for (j=0;j<=t;j++) f[0][j]=f[1][j];
}
printf("%d\n",f[0][t]);
}
/*一维*/
#include<cstdio>
int t,m,i,j;
int time[100],v[100];
int f[1001];
int main()
{
freopen("medic.in","r",stdin);
freopen("medic.out","w",stdout);
scanf("%d%d",&t,&m);
for (i=0;i<m;i++) scanf("%d%d",&time[i],&v[i]);
for (i=0;i<m;i++)
{
for (j=t;j>=time[i];j--)
if (f[j-time[i]]+v[i]>f[j]) f[j]=f[j-time[i]]+v[i];
}
printf("%d",f[t]);
}
2、装箱问题(30分)(box.pas)
问题描述
有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30=,每个物品有一个体积(正整数)。
要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。
输入格式:一行数据,第一个整数,表示箱子容量,每二个整数,表示有n个物品,接下来n个数,分别表示这n 个物品的各自体积
输出格式:一个整数,表示箱子剩余空间。
样例
输入:(box.in)
24 6 8 3 12 7 9 7
输出:(box.out)
0 一个整数,表示箱子剩余空间。
【思路】01背包,把V[I]当成体积也当成价值#include<cstdio>
int vm,n,i,j;
int v[30],f[20000];
int main(){
freopen("box.in","r",stdin);
freopen("box.out","w",stdout);
scanf("%d%d",&vm,&n);
for (i=0;i<n;i++) scanf("%d",&v[i]);
for (i=0;i<n;i++)
for (j=vm;j>=v[i];j--)
if (f[j-v[i]]+v[i]>f[j]) f[j]=f[j-v[i]]+v[i];
printf("%d\n",vm-f[vm]);
}
3、背包问题(bag.pas)
设有n种物品,记作A1、A2、…、An,对应于每个Ai(1<=i<=n)都有一个重量Awi和价值Avi(重量和价值都为正整数)。另外,对应于每个Ai,都有一件可代替它的“代用品”Bi,Bi的重量和价值分别为Bwi和Bvi。本题的任务是:选择这n件物品或其代用品的一个子集装进背包,使总重量不超过给定重量TOT,同时使总价值VAL最高。装填的第i步,要么装入Ai,要么装入Bi,要么Ai和Bi都不装。
输入数据:
从文件中读取,文件的格式如下:
第一行:n TOT (n<1000,tot<100000)
第二行:Aw1 Av1 Bw1 Bv1
第三行:Aw2 Av2 Bw2 Bv2
……
第n+1行:Awn Avn BWn BVn
输出数据:
输出入文件中只有一个数值VAL
例如:
input.txt
2 10
3 6 2 3
6 9 5 10
output.txt
16
【思路】01背包加强版,不同的是要多加一重判断,装A[I]较优还是B[I]较优
注意要用临时变量来更新F[I]的最优值,不然会出现装了A[I]又装B[I] (体积相等时)
体积有可能为0
#include<cstdio>
long n,tot,i,j;
long awi[1000],avi[1000],bwi[1000],bvi[1000],f[100000];
long Min(long a,long b)
{
if (a>b) return b;
return a;
}
int main(){
freopen("bag.in","r",stdin);
freopen("bag.out","w",stdout);
scanf("%ld%ld",&n,&tot);
for (i=0;i<n;i++) scanf("%ld%ld%ld%ld",&awi[i],&avi[i],&bwi[i],&bvi[i]);
for (i=0;i<n;i++)
for (j=tot;j>=0;j--){ //j=0
long max=f[j];
if (j>=awi[i] && f[j-awi[i]]+avi[i]>max) max=f[j-awi[i]]+avi[i];//f[j]=f[j-awi[i]]+avi[i];
if (j>=bwi[i] && f[j-bwi[i]]+bvi[i]>max) max=f[j-bwi[i]]+bvi[i];// f[j]=f[j-bwi[i]]+bvi[i];
f[j]=max;
}
printf("%ld\n",f[tot]);
}
4、开心的金明
(happy.pas/c/cpp)
【问题描述】
金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”。今天一早金明就开始做预算,但是他想买的东西太多了,肯定