poj 2923dp 상태 압축 + 백팩(화물차 2대 운반)

1535 단어
제목: n(1<=n<=10)개의 화물이 A지에서 B지로 운송되며, 각 화물의 무게는 와이이다.현재 두 개의 화물차가 있는데, 적재량은 각각 a와 b이다.이미 두 대의 화물차가 동시에 화물을 운송하고 돌아오는 것을 알고 있으며, 적어도 몇 번은 n개의 화물을 운송할 수 있느냐고 물었다.
사고방식: 먼저 n개의 화물에 대해 어떤 조합이 한 번에 운송될 수 있는지 테스트하고 상태 압축을 통해 한다.결과는 s수 그룹에 저장됩니다.이후 가방을 진행하면 한 상태state가 1위로 해당 화물을 선택한 것을 나타낸다.dp[state]는 state가 표시하는 화물 조합을 운송하는 데 필요한 최소 운송 횟수를 나타낸다.디테일 코드
#include <stdio.h>
#include <string.h>
#define min(a,b) ((a)<(b)?(a):(b))
#define INF 0x3fffffff
#define N 1100
int dp[N],s[N],w[N];
int T,n,a,b,m,c=1;
int test(int x){
	int i,j,used[1100],sum=0;
	memset(used,0,sizeof(used));
	used[0] = 1;
	for(i = 0;i<n;i++)
		if(x & (1<<i)){
			sum += w[i];//sum         
			for(j = a-w[i];j>=0;j--)
				if(used[j])
					used[j+w[i]] = 1;
		}
	for(i = a;i>=0;i--)//used[i] 1  i        a    ,         
		if(used[i]){
			if(sum-i<=b)
				return 1;
			return 0;		
		}
}
int main(){
	freopen("a.txt","r",stdin);
	scanf("%d",&T);
	while(T--){
		int i,j,top = 0;
		scanf("%d %d %d",&n,&a,&b);
		m = (1<<n)-1;//       
		for(i = 1;i<=m;i++)
			dp[i] = INF;
		dp[0] = 0;

		for(i = 0;i<n;i++)
			scanf("%d",&w[i]);

		for(i = 1;i<=m;i++)//                  
			if(test(i))
				s[top++] = i;

		for(i = 0;i<top;i++)
			for(j = m-s[i];j>=0;j--)
				if(!(s[i]&j))//        
					dp[s[i]|j] = min(dp[s[i]|j],dp[j]+1);

		printf("Scenario #%d:
%d

",c++,dp[m]); } return 0; }

좋은 웹페이지 즐겨찾기