1286最適なストレージ



説明
長さLのテープにn個のプログラム{1,2,...,n}を格納する.プログラムiを格納するには、テープの長さをLiとし、1<=i<=nとする必要がある.テープにできるだけ多くのプログラムを格納できるように、ストレージスキームを設計していただきたいと思います.最も多くのプログラムを保存することを前提として、テープの利用率を最大化する必要があります.
入力
第1の動作は、Tグループのテストデータがあることを示す整数Tである.
各試験データのセットについて、第1行は正の整数L(106を超えない)であり、テープの長さを表す.2行目は正の整数n(100を超えない)であり、n個のプログラムがあることを示す.3行目はn個の正の整数(各数の数値は100を超えない)であり、i番目の数値Liは、記憶に必要なテープ長がLiであり、各数がスペースで区切られていることを示す.
しゅつりょく
各テストデータのセットについて、最初の行は正の整数であり、テープに格納できるプログラムの最大数を示します.2行目は、テープに格納されているプログラムの合計テープ長を示す正の整数です.
サンプル入力
1
60
10
2 3 8 10 12 13 16 21 23 80

サンプル出力
6
60

 
リュックサックの問題に似たダイナミックな計画
#include <stdio.h>
#include <string.h>
main()
{
	int number,te;
	long int l;
	int a[101];
	int n;
	int i;
	int j;
	int cnt[10001];
	int sum;
	scanf("%d",&number);

	for(te=1;te<=number;te++)
	{  
		memset(cnt,0,sizeof(cnt));

		scanf("%ld",&l);
		scanf("%d",&n);
		for(i=1;i<=n;i++)
			scanf("%d",&a[i]);
  
		sum=0; 
		for(i=1;i<=n;i++)
			sum+=a[i];

		if(sum<l)
			l=sum;
		if(sum==l)
		{
			printf("%d
",n); printf("%d",sum); goto ABC; } for(i=1;i<=n;i++) for(j=l;j>=0;j--) { if(cnt[j-a[i]]+1>cnt[j]&&j-a[i]>=0) cnt[j]=cnt[j-a[i]]+1; else cnt[j]=cnt[j]; } for(j=l;j>=0;j--) if(cnt[j]!=0) break; printf("%d
",cnt[j] ); printf("%d",j); ABC: printf("
"); } }