Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2474 Accepted Submission(s): 973
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.
【题意】:宝石的数目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; }
#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; }