AreYouBusy HDU - 3535 (혼합 배낭)

새해 기간!
후배가 될 것으로, xiaoA 그녀가 수행하는 몇 가지 다른 일들이 그녀의 거의 미친 만드는,이 있기 때문에, 그녀의 AC에 문제에 대한 많은 시간이 아니라는 것을 인식하고 있습니다.
무엇보다, 그녀의 상사가 업무의 일부 세트를 위해, 그녀가 할 수있는 적어도 하나 개의 직업을 선택해야하지만, 몇 가지 설정을 위해, 그녀는 최대 하나의 보스에 의미가있는 수행하도록 선택할 수 있습니다 그녀를 알려줍니다. 그리고 다른 사람을 위해, 그녀는 그녀가 의지 할 수 있습니다. 우리는 단지 그녀가 "작업"으로 선택할 수있는 일을 정의합니다. 작업은 시간이 필요하고, xiaoA 낭포는 당신이 그녀에게 행복의 최대 포인트를주고 그 중 가장 좋은 세트를 선택할 수 있습니다 (그녀는 항상 작업을 할 용의가 있음을 의미)도 좋은 후배로 행복의 몇 가지 포인트를 제공합니다 (그녀는 상사의 조언을 따라야한다는 어떤 수단)?
입력
여러 테스트 케이스가 있습니다, 각각의 테스트 케이스는 두 개의 정수 N과 T로 시작 (0 <= N, T <= 100), n은 작업 세트 그녀를 할 수 있도록 당신이 선택하고 T 분하기 위해. 다음이이 세트 m 작업은, 상기 설정된 타입 S (선택해야 세트 0 약자이며, N이고 두 정수 시작 각각 설명의 세트, M, 및 S (0 <m <= 100) 적어도 1 일은, GI (0 <= CI, GI <= 100) 다음, 당신은) 자유롭게 정수 CI의 그 때는 m 쌍을 선택할 수있는 하나 (1) 대부분에서 선택해야합니다 세트에 대한 1 할, 2 할 를 마무리함으로써 얻을 수 행복의 끝과 GI 점 i 번째 작업 비용 CI 분을 의미한다. 하나의 작업은 한 번만 수행 할 수 있습니다.
출력
그녀가 무엇을 그녀의 보스 희망, 단지 출력을 마칠 수 없습니다 .if 각 테스트 케이스에 대한 한 줄은 우리가 모든 작업에서 선택할 수있는 행복의 최대 지점이 포함 -1.
입력 샘플
3 3
2 1
2 5
3 8
2 0
1 0
2 1
3 2
4 3
2 1
1 1

3 4
2 1
2 5
3 8
2 0
1
2 8
3 2
4 4
2 1
1 1

1 1
1 0
2 1

5 3
2 0
1 0
2 1
2 0
2 2
1 1
2 0
3 2
2 1
2 1
1 5
2 8
3 2
3-8
4-9
5-10
출력 예
5
13
-1
-1

문제의 의미 :
많은 그룹은 w 일부 항목, 가치 및 비용 V있다.
T.의 배낭 용량
각각의 선택은 대부분의 선택된 일부가 임의로 선택 될 수있다에서 선택된 적어도 몇몇 일부를 한정한다.
얼마나 많은 수요를 저장할 수 있습니다.
아이디어 :

  • 적어도 하나를 선택합니다. 세트 상태로부터, 및 전사 (이 단지 선택) (이상 상태가 다음 그룹 가능 옵션들로부터 선택되는 하나 이상에 선택 전사 된 한) 상태 천이를 시작 선택한
  • 위로 하나를 선택합니다. 집에서 직접 전송하고있는 상태가 될 수있다
  • 선택합니다. 이 그룹 배낭 01 일의 등가.
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int INF = 0x3f3f3f3f;
int dp[105][105];

int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        memset(dp,0,sizeof(dp));
        for(int i = 1;i <= n;i++)
        {
            int num,cnt;scanf("%d%d",&num,&cnt);
            if(cnt == 0)//至少选一个
            {
                for(int j = 0;j <= m;j++)dp[i][j] = -INF;
                for(int j = 1;j <= num;j++)
                {
                    int w,v;scanf("%d%d",&w,&v);
                    for(int k = m;k >= w;k--)
                    {
                        dp[i][k] = max(dp[i][k],dp[i][k - w] + v);//当前集和选,从”至少选了一个“的状态转移过来。
                        dp[i][k] = max(dp[i][k],dp[i - 1][k - w] + v);//至少选了一个,和只选了一个的状态。
                    }
                }
            }
            else if(cnt == 1)//至多选一个
            {
                for(int j = 0;j <= m;j++)dp[i][j] = dp[i - 1][j];
                for(int j = 1;j <= num;j++)
                {
                    int w,v;scanf("%d%d",&w,&v);
                    for(int k = m;k >= w;k--)
                    {
                        dp[i][k] = max(dp[i][k],dp[i - 1][k - w] + v);//上一个集合选,为选了一个
                    }
                }
            }
            else if(cnt == 2)//随便选
            {
                for(int j = 0;j <= m;j++)dp[i][j] = dp[i - 1][j];
                for(int j = 1;j <= num;j++)
                {
                    int w,v;scanf("%d%d",&w,&v);
                    for(int k = m;k >= w;k--)
                    {
                        dp[i][k] = max(dp[i][k],dp[i][k - w] + v);//普通01背包
                    }
                }
            }
        }
        dp[n][m] = max(dp[n][m],-1);
        printf("%d\n",dp[n][m]);
    }
    return 0;
}

게시 된 594 개 원래 기사 · 원 찬양 16 ·은 20000 +를 볼

추천

출처blog.csdn.net/tomjobs/article/details/103986719