nyoj311 完全背包
2016-04-04 18:44
148 查看
NYOJ311
时间限制:3000 ms | 内存限制:65535 KB
难度:4
描述
直接说题意,完全背包定义有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的体积是c,价值是w。求解将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大。本题要求是背包恰好装满背包时,求出最大价值总和是多少。如果不能恰好装满背包,输出NO
输入第一行: N 表示有多少组测试数据(N<7)。
接下来每组测试数据的第一行有两个整数M,V。 M表示物品种类的数目,V表示背包的总容量。(0<M<=2000,0<V<=50000)
接下来的M行每行有两个整数c,w分别表示每种物品的重量和价值(0<c<100000,0<w<100000)
输出对应每组测试数据输出结果(如果能恰好装满背包,输出装满背包时背包内物品的最大价值总和。 如果不能恰好装满背包,输出NO)
样例输入
样例输出
有时候完全背包问题,可以看成是图(带权有向图),初始时每个点之间的距离为INF(-INF) ,通过不断的加点更新距离( 两点之间加点(路径)来更新路径) ,得到,最长或最短路径。
----------------------------------------------[b]-----------------------------------------------------------------------------------------------------------[/b]
小技巧:
一般我们给dp进行初始化的时候
for(i=1;i<=v;i++)
dp[i] = -INF;
还有更简便的方法
memset(dp , -100 ,sizeof(dp));
dp[i] 不是-100 呦,虽然不知道为什么 ,测了一下是-1667457892 足够的小!!比 - 1<<30 还小!
---自己写的
#include<stdio.h>
#define INF 1000000
int main()
{
int m,v,c,w,n,i,j;
int dp[50005];
int a,b;
scanf("%d",&n);
while(n--)
{
scanf("%d %d",&m,&v);
dp[0] = 0; //细心
for(i=1;i<=v;i++)
dp[i] = -INF;
for(i = 0;i<m;i++)
{
scanf("%d %d",&a,&b);
for(j = a;j<=v;j++)
{
dp[j] = dp[j]>dp[j-a]+b?dp[j]:dp[j-a]+b;
}
}
if(dp[v] <0)printf("NO\n");
else
printf("%d\n",dp[v]);
}
return 0;
}
---最优答案
#include<stdio.h>
#include<string.h>
#define max(a,b) (a)>(b)?(a):(b)
int main()
{
int n,m,v,i,j,d[50005],a,b;
scanf("%d",&n);
while(n--)
{
scanf("%d%d",&m,&v);
memset(d,-100,sizeof(d));
d[0]=0; //细心 for(i=0;i<m;i++){scanf("%d%d",&a,&b);for(j=a;j<=v;j++)d[j]=max(d[j-a]+b,d[j]);}if(d[v]<0) printf("NO\n");else printf("%d\n",d[v]);}return 0;}
对了还有一点要说一下,这种推法超时啦!(输入完后整体后推的)
dp[0] = 0;
for(i=1;i<=v;i++)
dp[i] = -INF;
for(i=1;i<=v;i++)
for(j=0;j<m;j++)
if(i>=M[j][0])
dp[i] = dp[i]>dp[i-M[j][0]]+M[j][1]?dp[i]:dp[i-M[j][0]]+M[j][1];
}
完全背包
时间限制:3000 ms | 内存限制:65535 KB难度:4
描述
直接说题意,完全背包定义有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的体积是c,价值是w。求解将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大。本题要求是背包恰好装满背包时,求出最大价值总和是多少。如果不能恰好装满背包,输出NO
输入第一行: N 表示有多少组测试数据(N<7)。
接下来每组测试数据的第一行有两个整数M,V。 M表示物品种类的数目,V表示背包的总容量。(0<M<=2000,0<V<=50000)
接下来的M行每行有两个整数c,w分别表示每种物品的重量和价值(0<c<100000,0<w<100000)
输出对应每组测试数据输出结果(如果能恰好装满背包,输出装满背包时背包内物品的最大价值总和。 如果不能恰好装满背包,输出NO)
样例输入
2 1 5 2 2 2 5 2 2 5 1
样例输出
NO 1
有时候完全背包问题,可以看成是图(带权有向图),初始时每个点之间的距离为INF(-INF) ,通过不断的加点更新距离( 两点之间加点(路径)来更新路径) ,得到,最长或最短路径。
----------------------------------------------[b]-----------------------------------------------------------------------------------------------------------[/b]
小技巧:
一般我们给dp进行初始化的时候
for(i=1;i<=v;i++)
dp[i] = -INF;
还有更简便的方法
memset(dp , -100 ,sizeof(dp));
dp[i] 不是-100 呦,虽然不知道为什么 ,测了一下是-1667457892 足够的小!!比 - 1<<30 还小!
---自己写的
#include<stdio.h>
#define INF 1000000
int main()
{
int m,v,c,w,n,i,j;
int dp[50005];
int a,b;
scanf("%d",&n);
while(n--)
{
scanf("%d %d",&m,&v);
dp[0] = 0; //细心
for(i=1;i<=v;i++)
dp[i] = -INF;
for(i = 0;i<m;i++)
{
scanf("%d %d",&a,&b);
for(j = a;j<=v;j++)
{
dp[j] = dp[j]>dp[j-a]+b?dp[j]:dp[j-a]+b;
}
}
if(dp[v] <0)printf("NO\n");
else
printf("%d\n",dp[v]);
}
return 0;
}
---最优答案
#include<stdio.h>
#include<string.h>
#define max(a,b) (a)>(b)?(a):(b)
int main()
{
int n,m,v,i,j,d[50005],a,b;
scanf("%d",&n);
while(n--)
{
scanf("%d%d",&m,&v);
memset(d,-100,sizeof(d));
d[0]=0; //细心 for(i=0;i<m;i++){scanf("%d%d",&a,&b);for(j=a;j<=v;j++)d[j]=max(d[j-a]+b,d[j]);}if(d[v]<0) printf("NO\n");else printf("%d\n",d[v]);}return 0;}
对了还有一点要说一下,这种推法超时啦!(输入完后整体后推的)
dp[0] = 0;
for(i=1;i<=v;i++)
dp[i] = -INF;
for(i=1;i<=v;i++)
for(j=0;j<m;j++)
if(i>=M[j][0])
dp[i] = dp[i]>dp[i-M[j][0]]+M[j][1]?dp[i]:dp[i-M[j][0]]+M[j][1];
}
相关文章推荐
- 实现加减乘除的类
- 返回二维数组子数组联通和最大
- 数据结构学习-栈和队列(3)
- 删除指定目录下的所有文件和文件夹
- iOS 系统架构
- POJ 3264 Balanced Lineup(RMQ)
- jQuery $.each用法
- php文件上传的两种实现方法
- Mark Netlink
- HOG三线性插值
- 求和思想的应用
- Win10 输入法导致程序出错
- Xcode编译 No such file or directory
- LeetCode之7 --- Reverse Integer
- nyoj860 又见01背包
- YTU 3003: 括号匹配(栈和队列)
- POJ 1276 Cash Machine 多重背包O(n*m)算法
- 批量修改文件名
- OSX 使用“终端”远程登录linux主机
- 我 && yii2 (一)