华师一附中OI组

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 4673|回复: 18
打印 上一主题 下一主题

P1060 开心的金明

[复制链接]

738

主题

1485

帖子

5422

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
5422
跳转到指定楼层
楼主
发表于 2018-5-11 11:31:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
https://www.luogu.org/problemnew/show/P1060
题目描述
金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”。今天一早金明就开始做预算,但是他想买的东西太多了,肯定会超过妈妈限定的N元。于是,他把每件物品规定了一个重要度,分为5等:用整数1~5表示,第5等最重要。他还从因特网上查到了每件物品的价格(都是整数元)。他希望在不超过N元(可以等于N元)的前提下,使每件物品的价格与重要度的乘积的总和最大。

设第j件物品的价格为v[j],重要度为w[j],共选中了k件物品,编号依次为j1,j2,……,jk,则所求的总和为:

v[j1]*w[j1]+v[j2]*w[j2]+ …+v[jk]*w[jk]。(其中*为乘号)

请你帮助金明设计一个满足要求的购物单。

输入输出格式
输入格式:
输入的第1行,为两个正整数,用一个空格隔开:N m(其中N(<30000)表示总钱数,m(<25)为希望购买物品的个数。)

从第2行到第m+1行,第j行给出了编号为j-1的物品的基本数据,每行有2个非负整数 v p(其中v表示该物品的价格(v<=10000),p表示该物品的重要度(1~5))

输出格式:
输出只有一个正整数,为不超过总钱数的物品的价格与重要度乘积的总和的最大值(<100000000)。

输入输出样例
输入样例#1:
1000 5
800 2
400 5
300 5
400 3
200 2
输出样例#1:
3900
说明
NOIP 2006 普及组 第二题
回复

使用道具 举报

0

主题

4

帖子

38

积分

新手上路

Rank: 1

积分
38
推荐
发表于 2018-6-26 21:24:28 | 只看该作者
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int v[25],p[25],f[30005];
  4. int main(){
  5.     int n,m;
  6.     cin>>n>>m;
  7.     for(int i=1;i<=m;i++) cin>>v[i]>>p[i];
  8.     for (int i=1;i<=m;i++)
  9.         for(int j=n;j>=v[i];j--)
  10.            f[j]=max(f[j],f[j-v[i]]+v[i]*p[i]);
  11.     cout<<f[n];
  12.     return 0;
  13. }
复制代码
回复 支持 0 反对 1

使用道具 举报

2

主题

105

帖子

306

积分

中级会员

Rank: 3Rank: 3

积分
306
沙发
发表于 2018-5-12 11:57:23 | 只看该作者
  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <iostream>
  4. #include <cmath>
  5. #include <cstring>
  6. #include <set>
  7. using namespace std;
  8. int main()
  9. {
  10.     int f[110000]={0},v[70]={0},w[70]={0},i,w_all,n;
  11.     scanf("%d %d",&w_all,&n);
  12.     for(i=1;i<=n;i++)
  13.     {
  14.         int q;
  15.         scanf("%d %d",&w[i],&q);
  16.         v[i]=q*w[i];
  17.     }
  18.     for(i=1;i<=n;i++)
  19.         for(int j=w_all;j>=w[i];j--)
  20.             f[j]=max(f[j],f[j-w[i]]+v[i]);
  21.     printf("%d",f[w_all]);
  22.     return 0;
  23. }
复制代码

回复 支持 反对

使用道具 举报

9

主题

158

帖子

470

积分

华一学生

积分
470
QQ
板凳
发表于 2018-5-13 21:50:47 | 只看该作者
以下代码仅过了5个点,请老师指点:
  1. #include<iostream>
  2. using namespace std;
  3. int n,m;
  4. int f[25][30000];
  5. int w[25];
  6. short v[25];
  7. int main()
  8. {
  9.     cin>>n>>m;
  10.     for(int i=1; i<=m; i++)
  11.     {
  12.         cin>>w[i]>>v[i];
  13.         v[i]*=w[i];
  14.     }
  15.     for(int i=1; i<=m; i++)
  16.         for(int j=n; j>=w[i]; j--)
  17.         {
  18.             f[i][j]=f[i-1][j];
  19.             f[i][j]=max(f[i-1][j-w[i]]+v[i],f[i-1][j]);
  20.         }
  21.     cout<<f[m][n];
  22.     return 0;
  23. }
复制代码
回复 支持 反对

使用道具 举报

0

主题

30

帖子

91

积分

注册会员

Rank: 2

积分
91
地板
发表于 2018-5-19 19:54:31 | 只看该作者
  1. #include <cstdio>
  2. int p[26],v[26],f[26][30001];
  3. int max(int a,int b)
  4. {
  5.         if(a>=b)
  6.                 return a;
  7.         else
  8.                 return b;
  9. }
  10. int main()
  11. {
  12.         int n,m;
  13.         scanf("%d%d",&n,&m);
  14.         for(int i=1;i<=m;i++)
  15.                 scanf("%d%d",&p[i],&v[i]);
  16.         for(int i=1;i<=m;i++)  
  17.                 for(int q=0;q<=n;q++)
  18.         {  
  19.             f[i][q]=f[i-1][q];
  20.             if(q>=p[i])  
  21.                 f[i][q]=max(f[i-1][q],f[i-1][q-p[i]]+p[i]*v[i]);   
  22.         }
  23.         printf("%d",f[m][n]);
  24.         return 0;
  25. }
复制代码
回复 支持 反对

使用道具 举报

9

主题

158

帖子

470

积分

华一学生

积分
470
QQ
5#
发表于 2018-5-19 22:11:57 | 只看该作者
黄煦喆 发表于 2018-5-13 21:50
以下代码仅过了5个点,请老师指点:

AC:
  1. #include<iostream>
  2. using namespace std;
  3. int n,m;
  4. int f[25][30000];
  5. int w[25];
  6. int v[25];
  7. int main()
  8. {
  9.     cin>>n>>m;
  10.     for(int i=1; i<=m; i++)
  11.     {
  12.         cin>>w[i]>>v[i];
  13.         v[i]*=w[i];
  14.     }
  15.     for(int i=1; i<=m; i++)
  16.         for(int j=1; j<=n; j++)
  17.         {
  18.             f[i][j]=f[i-1][j];
  19.             if(j>=w[i])f[i][j]=max(f[i-1][j-w[i]]+v[i],f[i][j]);
  20.         }
  21.     cout<<f[m][n];
  22.     return 0;
  23. }
复制代码
回复 支持 反对

使用道具 举报

9

主题

89

帖子

292

积分

华一学生

积分
292
6#
发表于 2018-5-24 22:53:36 | 只看该作者
  1. #include<iostream>
  2. using namespace std;
  3. int maxv,n,i,j;
  4. int v[30],p[30];///v表示价格 p表示重要度
  5. int ans;
  6. void dfs(int x,int sumv,int sum)
  7. {
  8.     if (sumv>maxv) return;
  9.     else if (x>=n+1) ans=max(ans,sum);
  10.     else
  11.     {
  12.         dfs(x+1,sumv,sum);
  13.         dfs(x+1,sumv+v[x],sum+v[x]*p[x]);
  14.     }
  15. }
  16. int main()
  17. {
  18.     cin>>maxv>>n;
  19.     for (i=1;i<=n;i++) cin>>v[i]>>p[i];
  20.     dfs(1,0,0);
  21.     cout<<ans;
  22.     return 0;
  23. }
复制代码
回复 支持 反对

使用道具 举报

738

主题

1485

帖子

5422

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
5422
7#
 楼主| 发表于 2018-6-3 12:07:30 | 只看该作者
都很好,ZXY用的dfs,HXZ和WYL用的DP,但是想想为什么HXZ第一个程序只AC了5个点?
回复 支持 反对

使用道具 举报

7

主题

27

帖子

91

积分

注册会员

Rank: 2

积分
91
8#
发表于 2018-6-5 13:47:02 | 只看该作者
  1. #include <cstdio>
  2. #include <algorithm>
  3. using namespace std;

  4. int n,v[30],c[30],V,f[30005];

  5. int main()
  6. {
  7.     scanf ("%d%d",&V,&n);
  8.     for(int i=1;i<=n;i++)
  9.     {
  10.         scanf ("%d%d",&v[i],&c[i]);
  11.         c[i]*=v[i];
  12.     }
  13.     for(int i=1;i<=n;i++)
  14.     {
  15.         for(int j=V;j>=v[i];j--)
  16.         {
  17.             f[j]=max(f[j],f[j-v[i]]+c[i]);
  18.         }
  19.     }
  20.     printf("%d",f[V]);
  21.     return 0;
  22. }
复制代码
回复 支持 反对

使用道具 举报

2

主题

105

帖子

306

积分

中级会员

Rank: 3Rank: 3

积分
306
9#
发表于 2018-6-25 16:11:44 | 只看该作者
  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <iostream>
  4. #include <cmath>
  5. #include <cstring>
  6. #include <set>
  7. using namespace std;
  8. int main()
  9. {
  10.     int f[110000]={0},v[70]={0},w[70]={0},i,w_all,n;
  11.     scanf("%d %d",&w_all,&n);
  12.     for(i=1;i<=n;i++)
  13.     {
  14.         int q;
  15.         scanf("%d %d",&w[i],&q);
  16.         v[i]=q*w[i];
  17.     }
  18.     for(i=1;i<=n;i++)
  19.     {
  20.         for(int j=w_all;j>=w[i];j--)
  21.         {
  22.             f[j]=max(f[j],f[j-w[i]]+v[i]);
  23.         }
  24.     }
  25.     printf("%d",f[w_all]);
  26.     return 0;
  27. }
复制代码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|服务支持:DZ动力|华师一附中OI组  

GMT+8, 2024-12-26 14:11 , Processed in 0.140263 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表