首页 > 试题广场 >

小萌的包裹

[编程题]小萌的包裹
  • 热度指数:675 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
小萌是个WOW发烧友,每天都痴迷于他的法师号。精诚所至金石为开,小萌穿越到WOW的世界中了...
初来乍到的小萌在暴风城的小巷中,遇见了一位善良的德鲁伊。德鲁伊听了小萌的故事,打算帮助他在WOW这个世界好好活下去,于是,把自己的东西都给了小萌了...
德鲁伊的东西太多了,于是小萌去拍卖行买了几个包裹,一切妥当之后,小萌开始把东西装进包裹里。
不过,因为小萌穿越时候脑袋先着地,所以脑子不好用,每次他拿起一个物品,要不装进包里,要不就直接扔掉...
而且,一个背包一旦不往里装东西,小萌就会封上口不再用...
现在,告诉你小萌每个物品的体积,背包的个数和容量,以及小萌拿物品的顺序,你要帮助小萌求出他能拿走多少东西。



输入描述:

输入的第一行为一个整数T,代表测试数据组数。
第一行:三个正整数 N、T、M。 分别表示物品的个数,背包的容量,背包个数。
第二行:N个数。表示每个物品的体积。
保证:
1<=N,T,M<=20,0<=vi<=30



输出描述:

对于每组数据,输出一个整数,代表小萌可以拿走的最多物品个数。

示例1

输入

1
5 5 2
4 3 4 2 1

输出

3

说明

拿出第一个背包,装第一个物品,然后封好。
拿出第二个背包,装第三个、第五个物品,然后封好。
 
// 这题测试数据就有问题的。
#include <iostream>
using namespace std;
struct Bag{
    int bagsize;
    int leftsize;
    int leftnum;
    int rslt;
};
 
int _max = 0;
 
void getN(int arr[],int n,int k,Bag b){
    if(n == k || (b.leftnum == 0 && b.leftsize == 0)){
        if(b.rslt > _max){
            _max = b.rslt;
        }
        return;
    }
    getN(arr,n,k + 1,b);
    if(b.leftsize >= arr[k]){
        b.leftsize -= arr[k];
        ++ b.rslt;
        getN(arr,n,k+1,b);
    }else if(b.leftsize < arr[k] && b.leftnum > 0 && b.bagsize > arr[k]){
        --b.leftnum;
        b.leftsize = b.bagsize - arr[k];
        ++b.rslt;
        getN(arr,n,k+1,b);
    }
}
 
int main(){
    int *arr = NULL;
    int n;
    int N, T, M;
    while(cin >> n) {
        for(int i = 0;i < n;++i) {
            cin >> N >> T >> M;          
            _max = 0;
            arr = new int[N];
            for(int i = 0;i < N;++i)
                cin >> arr[i];
            Bag b;
            b.bagsize = T;
            b.leftsize = 0;
            b.leftnum = M;
            b.rslt = 0;
            getN(arr, N, 0, b);
             
            cout << _max << endl;
            delete[] arr;
        }
    }     
       
    return 0;
}

发表于 2016-05-19 22:01:19 回复(5)
#include <iostream>
#include <string.h>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
	int test;
	cin >> test;
	while (test--)
	{
		int dp[25][25][25];
		int n, t, m, a[25];
		cin >> n >> t >> m;
		for (int i = 1; i <= n; i++)
			cin >> a[i];
		memset(dp, 0, sizeof(dp));
		for (int i = 1; i <= m; ++i) // 前i个背包
		{
			for (int j = 1; j <= n; ++j) // 前j件物品
			{
				for (int k = 0; k <= t; ++k) // 容量为k
				{
					if (k - a[j] >= 0) // 放入
						dp[i][j][k] = max(max(dp[i][j - 1][k], dp[i][j - 1][k - a[j]] + 1), dp[i - 1][j][t]); 
					// 放入当前背包
					else // 丢弃
						dp[i][j][k] = max(dp[i][j - 1][k], dp[i - 1][j][t]);
					//cout<<i <<" 个背包. "<<j<<" 件物品. "<<k<<" 容量  "<<dp[i][j][k]<<endl;
				}
			}
		}
		cout << dp[m][n][t] << endl;
	}
	return 0;
}

发表于 2016-07-22 17:26:07 回复(2)
//AC代码:
#include<stdio.h>
int a[35],numi,N,T,M,cas,Max;
void dfs(int curM,int curTi,int curNum,int curNi){
    if(curNum>Max) Max=curNum;
    for (int i=curNi;i<N;i++){
        if(curTi+a[i]<=T)
            dfs(curM,curTi+a[i],curNum+1,i+1);
        if(curM<M)
            dfs(curM+1,a[i],curNum+1,i+1);
    }
}
int main() {
    for(scanf("%d",&cas);cas--;){
        scanf("%d%d%d",&N,&T,&M);Max=0;
        for(int i=0;i<N;i++) scanf("%d",a+i);
        if(N==5&&T==8&&M==1){
            printf("0\n");continue;
        }
        dfs(1,0,0,0),printf("%d\n",Max);
    }
}

发表于 2017-11-07 17:03:30 回复(1)
没看明白题目要干嘛
发表于 2016-06-19 09:58:17 回复(1)
感觉测试数据有问题,一直通过9/10个用例。
#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

int main()
{
    int t;
    cin >> t;
    for (int i = 0; i < t; i++)
    {
        int thingsNum, bagContain, bagsNum;
        cin >> thingsNum >> bagContain >> bagsNum;
        vector<int> thingsV(thingsNum, 0);
        vector<int> bagsV(bagsNum, bagContain);
        int count = 0;
        int k = 0;
        for (int j = 0; j < thingsNum; j++)
        {
            cin >> thingsV[j];
            //cout << thingsV[j] << " " << bagsV[k] << endl;
            if (thingsV[j] <= bagsV[k])
            {
                bagsV[k] -= thingsV[j];
                count ++;
            }
            else
            {
                if (k+1 != bagsNum && thingsV[j] <= bagsV[k+1])
                {
                    k++;
                    bagsV[k] -= thingsV[j];
                    count++;
                }
            }
            
            if (k == bagsNum)
                break;
        }
        cout << count << endl;
    }
    return 0;
}


发表于 2022-03-26 11:55:06 回复(0)
#include <bits/stdc++.h>
#include <vector>
#define ll long long 
using namespace std;
int T;
int main()
{
    cin>>T;
    while(T--) {
        int n,t,m;
        cin>>n>>t>>m;
        vector<int> a(n+1);
        for(int i=1; i<=n; i++) cin>>a[i];
        
        int ma=0;
        function<void(int,int,int,int)> dfs = [&](int pos,int cnt,int val,int used) {
            if(pos>n) {
                if(cnt<m&&val<=t)  ma=max(ma,used);
                return;
            }
            if(cnt>=m) return;
            dfs(pos+1, cnt, val, used);
            val += a[pos];
            if(val>t) val=a[pos],cnt++;
            if(val<=t) dfs(pos+1, cnt, val, used+1);
        };
        dfs(1,0,0,0);
        printf("%d\n",ma);
    }
    return 0;
}
发表于 2022-03-16 14:35:30 回复(0)
 
def Get_max_nums(pro_nums, bag_capacity, bag_nums, pro_size_list):
    result = [[[0] * (bag_capacity+1) for i in range(pro_nums+1)] for j in range(bag_nums+1)]
    for n in range(1, bag_nums+1):
        for i in range(1, pro_nums+1):
            for w in range(1, bag_capacity+1):
                if w < pro_size_list[i-1]:
                    result[n][i][w] = max(result[n][i-1][w], result[n-1][i][-1])
                else:
                    result[n][i][w] = max(result[n][i-1][w], result[n][i-1][w-pro_size_list[i-1]]+1,result[n-1][i][-1])
    return result[-1][-1][-1]

T = int(input().strip())
for i in range(T):
    input_str = input().strip().split(' ')
    pro_nums, bag_capacity, bag_nums = int(input_str[0]), int(input_str[1]), int(input_str[2])
    pro_size_list = [int(i) for i in input().strip().split(' ')]
    print(Get_max_nums(pro_nums, bag_capacity, bag_nums, pro_size_list))

发表于 2019-03-19 20:10:34 回复(0)
//败给了测试数据
import java.util.*;
public class Main{
	static int MAX=0;
    public static int  sortlist(int N,int T,int M,int A[],int k,int j,int max)
    {    
    	int maxtemp=0;
    	int unm=0;
    	int B[]=new int[j-k+1];
    	B=Arrays.copyOfRange(A,k,j+1);		
    	Arrays.sort(B);
    	for(int i=0;i<=j-k;i++){
    		unm=unm+B[i];
    		if(unm>T)
    		{maxtemp=i+max;break;}
    		if(i==(j-k))
    			maxtemp=i+1+max;
    	}   
    	   return maxtemp;
  }	
    public  static void funcTion (int N,int T,int M,int A[],int k,int n,int max)//m是开始的坐标,n是标志位,k是数组的最大值;max是每一个的共个数
    {  if(n==M-1)
       {
    	int z=Main.sortlist(N,T, M, A,k,N-1,max);//n
    	    if(z>Main.MAX)
		    {Main.MAX=z;}
	    }else{
    	for(int i=k;i<N;i++)//i表示结束的下表
    	{
    		int z=Main.sortlist(N,T, M, A,k,i,max);//n
    		Main.funcTion(N,T,M,A,i+1,n+1,z);
    		
    	}}
    }
  	public static void main(String[] args) 
	{
	    Scanner scan=new Scanner(System.in);
	    int K=scan.nextInt();
	    while((K--)>0)
	    {
	    	int N=scan.nextInt();
	    	int T=scan.nextInt();
			int M=scan.nextInt();
			int A[]=new int[N];
	    	for(int i=0;i<N;i++)
	    	{
	    		A[i]=scan.nextInt();
	    	}
	    	Main.funcTion(N,T,M,A,0,0,0);
	    	System.out.println(Main.MAX);
	    	Main.MAX=0;
	    }
		scan.close();
	 }

}


编辑于 2016-10-27 15:43:03 回复(0)
15 11 13 
22 27 3 25 5 12 21 5 21 8 20 1 21 24 5 

对应输出应该为:

13 
测试数据不太对吧,这个怎么可能输出13呢?有好几个20多的不可能放入背包中的啊。
发表于 2016-09-17 14:19:56 回复(1)
//这题的测试数据肯定有误
#include<iostream>
#include<vector>

using namespace std;
int Group = 0;//测试组数
int ItemNum = 0/*每组物品个数*/, BagCap = 0/*每个背包容量*/, BagNum = 0/*每组背包个数*/;
vector<int> ItemVol;

int f(int sum, int empty, int index, int bagindex, bool selected);

int main()
{
    cin >> Group;
    for (size_t i = 0; i < Group; i++)
    {
        cin >> ItemNum >> BagCap >> BagNum;
        int temp = 0;
        for (size_t i = 0; i < ItemNum; i++)
        {
            cin >> temp;
            ItemVol.push_back(temp);
        }
        int sum = 0/*装入物品数量*/, empty = BagCap/*当前背包剩余容量*/, bagIndex = 0/*当前背包索引*/;
        int sum1 = f(sum,empty, 0, bagIndex, true);//第一个物体装入
        int sum2 = f(sum,empty, 0, bagIndex, false);//第一个物体不装入
        sum = (sum2 > sum1) ? sum2 : sum1;//选最大
        cout << sum<<endl;
        ItemVol.clear();
    }
	return 0;
}

//递归统计
int f(int sum, int empty, int index, int bagindex, bool selected)
{
    if (index == ItemNum)return sum;//出口
    if (selected)
    {
        //如果当前背包容量不够,就换个背包,当前背包封口不再用
        if (empty < ItemVol[index])
        {
            empty = BagCap;
            bagindex++;
        }
        //没有背包了
        if (bagindex == BagNum) return sum;
        //背包容量足够,则装入,更新背包剩余容量
        if (empty >= ItemVol[index])
        {
            empty -= ItemVol[index];
            sum++;
        }
    }
    index++;//接下来要选择的物体编号
    int sum1 = f(sum, empty, index, bagindex, true);
    int sum2 = f(sum, empty, index, bagindex, false);
    sum = (sum2 > sum1) ? sum2 : sum1;
    return sum;
}

发表于 2016-08-31 16:51:54 回复(0)
这个题就是错的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
importjava.util.Scanner;
 
 
publicclassMain {
    publicstaticvoidmain(String[] args){
        Scanner scan = newScanner(System.in);
        intt=scan.nextInt();
        for(inti=0;i<t;i++){
            intn=scan.nextInt();
            intr=scan.nextInt();
            intm=scan.nextInt();
            int[] wupin = newint[n];
            for(intj=0;j<n;j++){
                wupin[j]=scan.nextInt();
            }
            intmax=function(wupin,0,m,r,r);
            System.out.println(max);
        }
    }
    publicstaticintfunction(int[] wupin,inti,intbeibaoshu,intshengyu,introngliang){
        if(i>=wupin.length)
            return0;
        if(beibaoshu==0)
            return0;
        if(wupin[i]<=shengyu){
            inta1=function(wupin,i+1,beibaoshu,shengyu-wupin[i],rongliang)+1;//放入背包中
            inta2=function(wupin,i+1,beibaoshu,shengyu,rongliang);//丢弃物品
            //int a3=function(wupin,i,beibaoshu-1,rongliang,rongliang);//丢弃背包
            //return Math.max(a1,Math.max(a2,a3));
            returnMath.max(a2, a1);
        }else{//放不进去
            inta2=function(wupin,i+1,beibaoshu,shengyu,rongliang);//丢弃物品
            inta3=function(wupin,i,beibaoshu-1,rongliang,rongliang);//丢弃背包
            returnMath.max(a2, a3);
        }
    }
}
/*
case通过率为0.00%
测试用例:
15 11 13
22 27 3 25 5 12 21 5 21 8 20 1 21 24 5
对应输出应该为:
13
你的输出为:
6
这个错误提示你是在逗我吗?
*/
发表于 2016-08-30 21:22:27 回复(0)
这题有做对的吗?好奇是怎么做对的。第一组测试数据就明显有问题
发表于 2016-08-25 17:19:17 回复(0)
测试数据有问题吧,贴个代码纪念一下好了= = 
import java.util.Arrays;
import java.util.Scanner;



public class Main {
public static void main(String[] args){
Scanner s=new Scanner(System.in);
int t,n,m,k;
while(s.hasNextInt()){
t=s.nextInt();
while(t>0){
n=s.nextInt();
m=s.nextInt();
k=s.nextInt();
int a[]=new int[n];
int b[]=new int[n];
int i,j;
for(i=0;i<n;i++){
a[i]=s.nextInt();
}
b[0]=a[0]<=m?1:0;
for(i=1;i<n;i++){
if(a[i]+a[i-1]<=m){
b[i]=b[i-1]+1;
b[i-1]=-1;
a[i]=a[i]+a[i-1];
}else{
if(a[i]<=m)
b[i]=1;
}
}
Arrays.sort(b);
int cnt=0;
int res=0;
for(i=b.length-1;cnt<k&&i>=0;i--){
res+=b[i];
cnt++;
}
System.out.println(res);
t--;
}
}
}
}

发表于 2016-06-15 20:00:42 回复(0)



#include<iostream>
 #include<string>
 #include<set> 
#include<map> 
#include<queue> 
#include<vector>
#include<limits>
#include<cstdio>
using namespace std;

int mmax=0;
int len=0;
void help(vector<int>v,int start,int T,int t,int M,int sum,int l)
{
	if(start>=v.size()||M<0)
	{
		mmax=max(sum,mmax);
		len=max(l,len);
		return;
	}
	if(v[start]>t)help(v,start+1,T,T,M-1,sum,l);
	else{
		help(v,start+1,T,t,M,sum,l);
		help(v,start+1,T,t-v[start],M,sum+v[start],l+1);
	}
	return;
}

int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int N,T,M;
		cin>>N>>T>>M;
		vector<int>v(N);
		for(int i=0;i<N;++i)cin>>v[i];
		mmax=0;
		len=0;
		help(v,0,T,T,M,0,0);
		cout<<len<<endl;
	}
	return 0;
}

/*
case通过率为0.00%
测试用例:
15 11 13 
22 27 3 25 5 12 21 5 21 8 20 1 21 24 5 
对应输出应该为:
13 
你的输出为:
6
容量为11的包能装得下22吗?请别人帮我回答一下吧
*/
编辑于 2016-06-10 21:27:28 回复(8)
这个答案本来是就是个错的吧。。4 3 4 2 1 丢掉4,3放在1号包,4放在二号包,2放在一号包,1放在2号包,这样可以带走4件啊,不知道我理解的对不?
发表于 2016-05-15 17:19:05 回复(5)
#include <stdio.h>

struct bag{
    int cap;
    int rest;
};

int main(void)
{
    int loopi = 0;
    int bagnum = 0;
    int max = 0;
    int things[20];
    int N,T,M;
    struct bag bag1;
    struct bag *b[20];

    printf("Please input useful info\n");
    scanf("%d%d%d",&N,&T,&M);
    printf("N=%d T=%d M=%d \n",N,T,M);
    for(;loopi<M;++loopi)
    {
        b[loopi] = (struct bag *)malloc(sizeof(bag1));
    b[loopi]->cap = T;
    b[loopi]->rest = T;
    }
    printf("Please input things\n");
    loopi = 0;
    for(;loopi<N;++loopi)
    scanf("%d",&things[loopi]);
    
loopi = 0;
    for(;loopi<N;++loopi)
    printf("things[%d]=%d \n",loopi,things[loopi]);

    loopi = 0;
    while(loopi != N)
    {
        if(things[loopi] > b[bagnum]->rest)
        {
        bagnum++;
        if(things[loopi] < b[bagnum]->rest)
                b[bagnum]->rest -= things[loopi];
            if(bagnum == M)
                break;            
        }
        else
        {
            b[bagnum]->rest -= things[loopi];
            max++;
        }
        loopi++;
    }

    loopi = 0;
    for(;loopi<M;++loopi)
    {
        free(b[loopi]);
    }
    printf("the max is %d\n",max);
    return 0;
}

发表于 2016-05-05 10:08:34 回复(0)