1. 程式人生 > >HDU 2660 Accepted Necklace (DFS)

HDU 2660 Accepted Necklace (DFS)

%d stones 01背包 pla time 要求 highest size bits

Accepted Necklace

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2474 Accepted Submission(s): 973


Problem Description I have N precious stones, and plan to use K of them to make a necklace for my mother, but she won‘t accept a necklace which is too heavy. Given the value and the weight of each precious stone, please help me find out the most valuable necklace my mother will accept.

Input The first line of input is the number of cases.
For each case, the first line contains two integers N (N <= 20), the total number of stones, and K (K <= N), the exact number of stones to make a necklace.
Then N lines follow, each containing two integers: a (a<=1000), representing the value of each precious stone, and b (b<=1000), its weight.
The last line of each case contains an integer W, the maximum weight my mother will accept, W <= 1000.

Output For each case, output the highest possible value of the necklace.

Sample Input 1 2 1 1 1 1 1 3

Sample Output 1

【題意】:寶石的數目n,制成項鏈所需的寶石個數k,然後再給出每個寶石的價值v與重量w,還有母親會接受的最大重量,求出在小於等於最大重量範圍內,項鏈的價值盡可能大。

【分析】:因為數據不大可用dfs,也可以用01背包。

【代碼】:

技術分享
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#define ll long long
using namespace std;
int maxn,n,k,wei;
int vis[21];
struct node
{
    int v,w;
}a[21];
/*
給出寶石的數目n,制成項鏈所需的寶石個數k,然後再給出每個寶石的價值與重量,
還有母親會接受的最大重量,求出在小於等於最大重量範圍內,項鏈的價值盡可能大。*/
void dfs(int v, int w, int x, int s)//x:枚舉下標,s:遍歷深度(個數)
{
    if(w==wei||s==k)
    {
        if(maxn<v)
            maxn=v;
        return ;
    }
    for(int i=x;i<=n;i++)    
    //這個地方下標直接從x開始,因為寶石並沒有要求序列問題只是求價值和,所以不需要考慮重復情況,是個很大的剪枝  
    //舉例: 3 4 5 6 == 4 3 5 6 == 5 3 6 4雖然序列不同,但是價值和相同,這樣的只需要搜一次即可也就是前面搜過的重量不再搜  
    {
        if(!vis[i] && w+a[i].w <= wei)//未訪問+未越界(小於等於最大重量範圍
        {
            vis[i]=1;
            dfs(v+a[i].v, w+a[i].w, i+1, s+1);
            vis[i]=0;
        }
    }
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        cin>>n>>k;
        for(int i=0;i<n;i++)
            cin>>a[i].v>>a[i].w;
        cin>>wei;
        memset(vis,0,sizeof(vis));
        maxn=-1;
        dfs(0,0,0,0);
        cout<<maxn<<endl;
    }
    return 0;
}
DFS 技術分享
#include <cstdio>  
#include <cstring>  
int max(int x, int y)  
{  
    return x>y?x:y;  
}  
int dp[1017][21];  
int main()  
{  
    int W,val[1017],wei[1017];  
    int n, k, t, i, j, l;  
      
    while(~scanf("%d",&t))  
    {  
        while(t--)  
        {  
            memset(dp,0,sizeof(dp));  
            scanf("%d %d",&n,&k);  
            for(i = 0 ;i < n; i++)  
            {  
                scanf("%d %d",&val[i],&wei[i]);  
            }  
            scanf("%d",&W);  
            for(i = 0; i < n; i++)  
            {  
                for(l = W; l >= wei[i]; l--)  
                {  
                    for(j = 1; j <= k; j++)  
                    {  
                        dp[l][j] = max(dp[l][j],dp[l-wei[i]][j-1]+val[i]);  
                    }  
                }  
            }  
            printf("%d\n",dp[W][k]);  
        }  
    }  
    return 0;  
}  
01背包

HDU 2660 Accepted Necklace (DFS)