G Greedy Tino

G  Greedy Tino

 Description

         Tinowrote a long long story. BUT! in Chinese...

         SoI have to tell you the problem directly and discard his long long story. Thatis tino want to carry some oranges with "Carrying pole", and he mustmake two side of the Carrying pole are the same weight. Each orange have its'weight. So greedy tino want to know the maximum weight he can carry.

Input

         Thefirst line of input contains a number t, which means there are t cases of thetest data.

         foreach test case, the first line contain a number n, indicate the number oforanges.

         thesecond line contains n numbers, Wi, indicate the weight of each orange

         nis between 1 and 100, inclusive. Wi is between 0 and 2000, inclusive. the sumof Wi is equal or less than 2000.

Output

         Foreach test case, output the maximum weight in one side of Carrying pole. If youcan't carry any orange, output -1. Output format is shown in Sample Output.

Sample Input

1

5

1 2 3 4 5

Sample Output

Case 1: 7


標程說這是一段很典型的DP問題!

爲什麼自己想了這麼久就沒想到呢!

——路漫漫其修遠兮,吾將上下而求索……

這是一個挑擔子問題,話說很久以前有個人很貪心,想多挑點橘子回家,人家還有要求的。知道擔子兩邊得一樣重會輕鬆點。這不問題就出來,現在有這麼多橘子,要你放入兩邊的筐裏,讓人家能輕輕鬆鬆多挑點回家。

dp[i][j]表示放入或不放入第i個橘子後,重量相差爲j時的最優解(我選擇較輕的筐的重量)。

第i個橘子分3種情況:

1、放入得較重的筐裏;

2、放入較輕的筐裏(這時可能會變爲較重的一方);

3、不放入;

三種情況取最優解即可;

有沒有聽說過重量爲0的橘子啊!真神奇啊。。得注意

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

#define N 110
#define S 2010
int dp[N][S+1];
int data[N], s[N];

int main()
{
    int cases, t;
    scanf("%d", &cases);
    t = 1;
    
    while(t <= cases)
    {
            int n;
            scanf("%d", &n);
            int i,j;
            for(i=0; i<n; i++)
            {
            scanf("%d", &data[i]);
            }
            
            memset(dp, -1, sizeof(dp));
            
            for(i=0; i<n; i++)
            dp[i][data[i]] = 0;
            //dp[0][0]=0;
            for(i=1; i<n; i++)
            {
                        for(j=0; j<=S; j++)
                        {
                            if(dp[i-1][j] >= 0)
                            {
                             if(data[i]+j<=S && dp[i][data[i]+j] < dp[i-1][j])
                                        dp[i][data[i]+j] = dp[i-1][j];
                              if(data[i] >= j)
                              {
                                     if(dp[i][data[i]-j] < dp[i-1][j] + j)
                                      dp[i][data[i]-j] = dp[i-1][j]+j;
                                                     
                                 }
                                else if(data[i] < j)
                               {
                                       if(dp[i][j-data[i]] < dp[i-1][j] + data[i])
                                            dp[i][j-data[i]] = dp[i-1][j]+data[i];
                                 }
                                                     
                               }
                                               
                        }
                        
                        for(j=0; j<=S; j++)
                         if(dp[i][j] < dp[i-1][j]) 
                         dp[i][j] = dp[i-1][j];

                }                               
              printf("Case %d: %d\n", t, dp[n-1][0]);  
            t++;         
            }
            //system("pause");
    return 0;
    }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章