# 背包专题、

HDU 2546

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int qq=1000+10;
int num[qq];
int dp[qq];
int main()
{
int n;
while(scanf("%d",&n)!=EOF){
if(!n)	break;
for(int i=1; i<=n; ++i)
scanf("%d",&num[i]);
int m;scanf("%d",&m);
if(m<5){	//少考虑这个情况
printf("%d\n",m);
continue;
}
m-=5;
memset(dp,0,sizeof(dp));
sort(num+1,num+n+1);
for(int i=1; i<=n-1; ++i)
for(int j=m; j>=num[i]; --j)	//从后往前取保证每个数只取一次、
dp[j]=max(dp[j], dp[j-num[i]]+num[i]);
printf("%d\n",m+5-dp[m]-num[n]);
}
return 0;
}

HDU 1203

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int qq=1e4+10;
double dp[qq];
int val[qq];
double bility[qq];
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
if(n==0&&m==0)	break;
for(int i=0; i<m; ++i){
scanf("%d%lf",&val[i],&bility[i]);
bility[i]=1-bility[i];
}
for(int i=0; i<=n; ++i)	dp[i]=1.0;
for(int i=0; i<m; ++i)
for(int j=n; j>=val[i]; --j)
dp[j]=min(dp[j], dp[j-val[i]]*bility[i]);
printf("%.1lf%%\n",(1.0-dp[n])*100);

}
return 0;
}

HDU 2639

#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
const int qq = 105;
int n,v,k;
int price[qq],value[qq];
int a[35],b[35];
int dp[qq*10][35];
int main()
{
int t;scanf("%d",&t);
while(t--){
scanf("%d%d%d",&n,&v,&k);
int i,j,l,x,y,z;
for(i=1; i<=n; ++i)	scanf("%d",&value[i]);
for(i=1; i<=n; ++i)	scanf("%d",&price[i]);
memset(dp, 0, sizeof(dp));
for(i=1; i<=n; ++i)
for(j=v; j>=price[i]; --j){
for(l=1; l<=k; ++l){
a[l]=dp[j][l];
b[l]=dp[j-price[i]][l]+value[i];
}
x=y=z=1;
a[l]=b[l]=-1;
while(z<=k && (a[x]!=-1 || b[y]!=-1)){
if(a[x]>b[y])	dp[j][z]=a[x],x++;
else		dp[j][z]=b[y],y++;
if(dp[j][z]!=dp[j][z-1])	z++;
}
}
printf("%d\n",dp[v][k]);
}
return 0;
} 

HDU 1114

#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int qq=5510;
const int MAX=1e8;
int price[qq],value[qq];
int dp[100100];
int main()
{
int t;scanf("%d",&t);
while(t--){
int n,m;scanf("%d%d",&n,&m);
int v=m-n;
int k;scanf("%d",&k);
for(int i=0; i<k; ++i)
scanf("%d%d",&value[i],&price[i]);
for(int i=1; i<=v; ++i)	dp[i]=MAX;
dp[0]=0;
for(int i=0; i<k; ++i)	//这里是k不是n、习惯性的当成n了
for(int j=price[i]; j<=v; ++j)	//以后还是不要出现n表示别的东西吧、
dp[j]=min(dp[j], dp[j-price[i]]+value[i]);
if(dp[v]!=MAX)	printf("The minimum amount of money in the piggy-bank is %d.\n",dp[v]);
else		printf("This is impossible.\n");
}
return 0;
}

HDU 2191

#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int qq = 205;
int price[qq*10],value[qq*10];
int dp[qq];
int main()
{
int t;scanf("%d",&t);
while(t--){
int n,m;scanf("%d%d",&n,&m);
int k=0;
int c,a,b;
for(int i=0; i<m; ++i){
scanf("%d%d%d",&a,&b,&c);
int t=1;
while(c>t){
price[k]=t*a;
value[k]=t*b;
c=c-t;
k++;
t<<=1;
}
if(c>0){
price[k]=c*a;
value[k]=c*b;
k++;
}
}
memset(dp, 0, sizeof(dp));
for(int i=0; i<k; ++i)
for(int j=n; j>=price[i]; --j)
dp[j]=max(dp[j], dp[j-price[i]]+value[i]);
printf("%d\n",dp[n]);
}
return 0;
}

HDU 1059

#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<stack>
#include<vector>
#include<utility>
using namespace std;
const int qq = 1e5+10;
int price[qq],value[qq];
int dp[qq];
int num[10];
int main()
{
int k=1;
while(scanf("%d",&num[1])!=EOF){
int count=0;
int c=num[1];
for(int i=2; i<=6; ++i){
scanf("%d",&num[i]);
c+=num[i];
}
if(c==0)	break;
int sum=0;
for(int i=1; i<=6; ++i){
int t=1;
sum+=i*num[i];
while(num[i]>=t){
price[count]=t*i;
value[count]=t*i;
count++;
num[i]=num[i]-t;
t=t<<1;
}
if(num[i]){
price[count]=i*num[i];
value[count]=i*num[i];
++count;
}
}
printf("Collection #%d:\n",k++);
if(sum%2==1){
printf("Can't be divided.\n\n");
continue;
}
memset(dp, 0, sizeof(dp));
for(int i=0; i<count; ++i)
for(int j=sum/2; j>=price[i]; --j)
dp[j]=max(dp[j], dp[j-price[i]]+value[i]);
if(dp[sum/2]==sum-sum/2)	printf("Can be divided.\n");
else	printf("Can't be divided.\n");
printf("\n");
}
return 0;
}

HDU 3466

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int qq=550;
struct Item
{
int p,q,w;
int t;
bool operator < (const Item a)
{
return t<a.t;
}
}item[qq];
int n,m;
int dp[qq*10];	//注意dp的范围、
int Quicksort(int l, int r)
{
int i=l,j=r;
int x=item[l].t;
Item c=item[l];	//很久没写快排了、 今天一写 错误竟然那么多、
while(i<j){		//感觉我有点死记模版了、  但是思路我确实是知道的、
while(i<j && item[j].t>=x)	--j;		//下次以思路来代模版、
item[i]=item[j];
while(i<j && item[i].t<=x)	++i;
item[j]=item[i];
}
item[i]=c;
return i;
}
void Quick(int l, int r)
{
if(l<r){
int temp=Quicksort(l,r);
Quick(l,temp);
Quick(temp+1, r);
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF){
for(int i=0; i<n; ++i){
scanf("%d%d%d",&item[i].p,&item[i].q,&item[i].w);
item[i].t=item[i].q-item[i].p;
}
Quick(0,n-1);
//for(int i=0 ;i<n; ++i)
//	printf("%d\n",item[i].t);
//	sort(item,item+n);
memset(dp, 0, sizeof(dp));
for(int i=0; i<n; ++i)
for(int j=m; j>=item[i].q; --j)
dp[j]=max(dp[j], dp[j-item[i].p]+item[i].w);
printf("%d\n",dp[m]);
}
return 0;
}

POJ 2063

#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int qq=5e4+10;
const int inf=1e9;
int dp[qq],price[110],value[110];
int main()
{
int t;scanf("%d",&t);
while(t--){
int n,m;scanf("%d%d",&n,&m);
int k;scanf("%d",&k);
for(int i=1; i<=k; ++i){
scanf("%d%d",&price[i],&value[i]);
price[i]/=1000;		//对背包大小进行压缩、
}
int val=n;
for(int i=1; i<=m; ++i){
int maxn=0;
int s=val/1000;	//继续压缩、
memset(dp, 0, sizeof(dp));
for(int j=1; j<=k; ++j)
for(int l=price[j]; l<=s; ++l)
dp[l]=max(dp[l], dp[l-price[j]]+value[j]);
val+=dp[s];	//本金+利息
}
printf("%d\n",val);
}
return 0;
}

POJ 3181

#include<cstdio>
#include<cstring>
const int qq=1000+10;
typedef long long ll;
ll a[qq];
ll b[qq];
int main()
{
int n,k;scanf("%d%d",&n,&k);
ll inf=1;
for(int i=0; i<18; ++i)	inf*=10;
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
a[0]=1;		//优化到一维后注意初状态、
for(int i=1; i<=k; ++i)
for(int j=1; j<=n; ++j){
if(j<i){	//j<i说明j-i是个负数 不存在dp[j-i][i]的情况 ;
continue;
}
b[j]=b[j]+b[j-i]+(a[j]+a[j-i])/inf;
a[j]=(a[j]+a[j-i])%inf;
}
if(b[n]!=0)	printf("%I64d%018I64d",b[n],a[n]);
else	printf("%I64d\n",a[n]);
return 0;
}

POJ 2184

#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
int dp[200010];
int v[110],w[110];
int main(){
int n;
scanf("%d",&n);
for(int i=0; i<n; ++i)
scanf("%d%d",&v[i],&w[i]);
for(int i=0; i<=200000; ++i)	dp[i]=-INF;
dp[100000]=0;
for(int i=0; i<n; ++i)
if(v[i]>0){
for(int j=200000; j>=v[i]; --j)
if(dp[j-v[i]]>-INF)
dp[j]=max(dp[j], dp[j-v[i]]+w[i]);
}
else{
for(int j=0; j<=200000+v[i]; ++j)
if(dp[j-v[i]]>-INF)
dp[j]=max(dp[j], dp[j-v[i]]+w[i]);
}
int maxn=0;
for(int i=100000; i<=200000; ++i)
if(dp[i]>=0 && dp[i]+i-100000>maxn)
maxn=dp[i]+i-100000;
printf("%d\n",maxn);
return 0;
}

HDU 2955

#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int qq = 105;
int v[qq];
double probli[qq];
double dp[qq*100];
int main()
{
int t;scanf("%d",&t);
while(t--){
double lower;scanf("%lf",&lower);
int n;scanf("%d",&n);
int sum=0;
lower=1.0-lower;
for(int i=0; i<n; ++i){
scanf("%d%lf",&v[i],&probli[i]);
sum+=v[i];
probli[i]=1-probli[i];
}
// 通过这题我知道了初始状态的重要性、
//而且这题的钱数都是一些特定的数、 有些状态可能达不到、比如
//第二组sample input  偷取1钱的安全概率始终是0、 因为这个状态不存在、
//还要记得每个状态都是由前面的状态递推而来、
//所以初始状态真的很重要、
for(int i=1; i<=sum; ++i)	dp[i]=0;
dp[0]=1;		//当盗取0钱的时候 安全概率肯定是1、
for(int i=0; i<n; ++i){
for(int j=sum; j>=v[i]; --j){
dp[j]=max(dp[j], dp[j-v[i]]*probli[i]);
//	printf("%lf ",dp[j]);
}
//printf("\n");
}
int maxn=0;
for(int i=1; i<=sum; ++i)
if(dp[i]>=lower&&maxn<i)
maxn=i;
printf("%d\n",maxn);
}
return 0;
} 

HDU 4342

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
const int qq = 200 + 10;
int group[qq][qq];	//代表第i组第j个物品的位置、(存的物品是位置)
int dp[40010];
struct Node
{
int x,y;
int v,t;
bool operator < (const Node a)	//考虑到斜率x可能为0、所以用乘法来比较
{
if(y*a.x==x*a.y)	return y<a.y;
return y*a.x<x*a.y;

}
}node[qq];
int main()
{
int n,m;
int t=1;
while(scanf("%d%d",&n,&m)!=EOF){
for(int i=0; i<n; ++i)
scanf("%d%d%d%d",&node[i].x,&node[i].y,&node[i].t,&node[i].v);
sort(node, node+n);
int kind=0;
for(int i=0; i<n; ++i){
group[kind][0]=0;
group[kind][++group[kind][0]]=i;
int x1=node[i].x;
int y1=node[i].y;
int a=node[i].t;
int b=node[i].v;
for(i++; i<n; ++i){	//进行分组、
int x2=node[i].x;
int y2=node[i].y;
a+=node[i].t;
b+=node[i].v;
if(x1*y2==x2*y1){
group[kind][++group[kind][0]]=i;
node[i].t=a;
node[i].v=b;
}
else{
--i;break;
}
}
kind++;
}
memset(dp, 0, sizeof(dp));	//其实和01背包差不多、
for(int k=0; k<kind; ++k)	//预处理起来麻烦一点、
for(int j=m; j>=0; --j)
for(int i=1; i<=group[k][0]; ++i)
if(j-node[group[k][i]].t>=0)
dp[j]=max(dp[j], dp[j-node[group[k][i]].t]+node[group[k][i]].v);
printf("Case %d: %d\n",t++,dp[m]);
}
return 0;
}

• 本文已收录于以下专栏：

举报原因： 您举报文章：背包专题、 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)