0-1背包 VIOJ1025
P1025小飞侠的游园方案
请 登录 后递交
描述
菜虫:你的题目是……我们的情报组织探听到敌人的重要将领——小飞侠星期天会邀他的灵儿妹妹到公园去玩。公园里有很多娱乐项目,可并不是每一项他们都喜欢,所以他们对每一项都进行了“喜欢度”的评分。因为小飞侠也是一个了不起的角色,所以他一定会选择在有限时间内的最好的方案。现在要你做的就是找出在规定时间内他们选择哪几项不同的活动可以使其“喜欢度”之和达到最大,据此我们就可以知道他会在哪些地方出现,从而在那里派人看守了。
小智:(灯泡一亮)每个地方都派人看守不就行了?!
“当~~~”
菜虫:(手执八公分直径炒锅,筋)……你是白痴吗?-_-##(都派人去看守的话我们会有多少桌三缺一?!)听好了,输入格式是第一行一个正整数N(1<=N<=100)表示总共的娱乐项目数;第二行一个正整数表示规定的时间t(0<t<1000);下面有N行,其中第i+2行有两个正整数fi(0<=fi<=100)和ti(0<ti<=100),分别表示对项目i的“喜欢度”和它所耗费的时间。输出的时候在第一行输出最大的“喜欢度”之和,下面给你一个样例:
样例1
样例输入1[复制]
3 5 1 2 5 5 4 3
样例输出1[复制]
5
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667#include<cstdio>
#include<cstring>
#include<algorithm>
using
namespace
std;
//01背包二维正写写法
int
p[107],w[107],dp[107][1007];
int
main()
{
int
N,T;
scanf
(
"%d%d"
,&N,&T);
for
(
int
i=1;i<=N;i++)
{
scanf
(
"%d%d"
,&p[i],&w[i]);
}
memset
(dp,0,
sizeof
(dp));
for
(
int
i=1;i<=N;i++)
{
for
(
int
j=0;j<=T;j++)
{
if
(j>=w[i])
dp[i][j] = max(dp[i-1][j],dp[i-1][j-w[i]]+p[i]);
else
dp[i][j] = dp[i-1][j];
}
}
printf
(
"%d"
,dp[N][T]);
}
//01背包二维逆写写法
int
p[107],w[107],dp[107][1007];
int
main()
{
int
N,T;
scanf
(
"%d%d"
,&N,&T);
for
(
int
i=1;i<=N;i++)
{
scanf
(
"%d%d"
,&p[i],&w[i]);
}
memset
(dp,0,
sizeof
(dp));
for
(
int
i=1;i<=N;i++)
{
for
(
int
j=T;j>=0;j--)
{
if
(j>=w[i])
dp[i][j] = max(dp[i-1][j],dp[i-1][j-w[i]]+p[i]);
else
dp[i][j] = dp[i-1][j];
}
}
printf
(
"%d"
,dp[N][T]);
}
//01背包1维写法,只能逆写
int
p[107],w[107],dp[1007];
int
main()
{
int
N,T;
scanf
(
"%d%d"
,&N,&T);
for
(
int
i=1;i<=N;i++)
scanf
(
"%d%d"
,&p[i],&w[i]);
memset
(dp,0,
sizeof
(dp));
for
(
int
i=1;i<=N;i++)
for
(
int
j=T;j>=w[i];j--)
dp[j] = max(dp[j],dp[j-w[i]]+p[i]);
printf
(
"%d"
,dp[T]);
}