hdu 2660 Accepted Necklace(01背包与dfs两种解法)

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=2660

DFS解法:

//因为stone个数才30,尝试看看暴力dfs解决此题(枚举) 
/*

*/

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

const int maxn=30;
const int maxc=1005;

int c,n,k,w,ans;
int a[maxn],b[maxn]; //a表示价值,b表示重量 

//dfs(已经遍历的stone,necklace上的stone,necklace上stone的总重量,当前总价值) 
void dfs(int curt,int curn,int curw,int curv){ 
    
    if(curn>k || curt>n || curw>w )
        return;
    if(curv>ans)
        ans=curv;
    for(int i=curt+1;i<=n;i++)//curt前面的一定无需遍历 
        dfs(i,curn+1,curw+b[i],curv+a[i]);
}

int main (){
    cin>>c;
    while(c--){
        
        cin>>n>>k;//n为stone总个数,k为necklace所能容纳的个数 
        for(int i=1;i<=n;i++)
            cin>>a[i]>>b[i];
        cin>>w;
        ans=0;
        dfs(0,0,0,0);
        cout<<ans<<endl;
    }
    return 0;
}  
View Code

DP解法:

/*
要求在n个石头中选k个放入容量为w的背包中,使得总价值最大
 
普通的01背包问题是在n个问题中选择使得总价值最大,不论选择几个
因为有n次的迭代更新,最终有dp[w]为最优解

此题设置dp[i][j][t]表示第i次迭代中,容量为j,含有t个物品的背包的最优解 
dp[i][j][t] = max( dp[i-1][j-b[i]][t-1]+a[i] )
简化为dp[j][t] = max( dp[j-b[i]][t-1]+a[i] ) 

for 1..n
    for w..b[i]
        for 1..i
            if( dp[j-b[i]][t-1]+a[i]>dp[j][t] )
                dp[j][t]=dp[j-b[i]][t-1]+a[i];
*/

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

const int maxn=30;
const int maxc=1005;

int c,n,k,w;
int a[maxn],b[maxn]; //a表示价值,b表示重量 
int dp[maxc][maxn]; 

int bp(){
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=n;i++)
        for(int j=w;j>=b[i];j--)
            for(int t=1;t<=k;t++)
                if( dp[j-b[i]][t-1]+a[i]>dp[j][t] )
                    dp[j][t]=dp[j-b[i]][t-1]+a[i];
    return dp[w][k];
}

int main (){
    cin>>c;
    while(c--){
        
        cin>>n>>k;
        for(int i=1;i<=n;i++)
            cin>>a[i]>>b[i];
        cin>>w;
        
        cout<<bp()<<endl;
    }
    return 0;
} 
View Code
原文地址:https://www.cnblogs.com/neverchanje/p/3552463.html