题目链接http://acm.hdu.edu.cn/showproblem.php?pid=2660
DFS解法:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
//因为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; }
DP解法:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
/* 要求在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; }