P1060
这个东西的价值是重要度*价格,然后物品种类放外层
#include<iostream>
#include<math.h>
using namespace std;
int dp[10000000];
int main()
{
int N,M,a,b,c;
cin>>N>>M;
for(int i=1;i<=M;i++)
{
cin>>a>>b;
c=a*b;
for(int j=N;j>=a;j--)这里是a,包的承载量和价钱有关
dp[j]=max(dp[j],dp[j-a]+c);
}
cout<<dp[N];
return 0;
}
P1049
有一点点绕,因为这个背包的物品和价值都是它的容积,然后就是只要有一维,一维里面减去的和外面加上的价值都是a
在#include<iostream>//价值和体积等价
#include<math.h>
using namespace std;
int dp[476587698];
int main()
{
int V,n,a;
cin>>V>>n;
for(int i=1;i<=n;i++)
{cin>>a;
for(int j=V;j>=a;j--)
{
dp[j]=max(dp[j],dp[j-a]+a);
}
}
cout<<V-dp[V];
}
当然还是把总的n放在外面的,但后面其实用不上
P1734
选取和不超过s,那么就用循环,循环里面判断约数,可以选择的数不超过s就可以,
a[i]里面存每一个物品的价值
然后约数采用背包思想
//s是背包的容量,价值是和
#include<iostream>
int a[145435676],dp[2135564];
using namespace std;
int main()
{
int S;
cin>>S;
for(int i=1;i<S;i++)
{
for(int j=1;j<i;j++)
{if(i%j==0)
a[i]+=j;
}
}
for(int i=1;i<=S;i++)
for(int j=S;j>=i;j--)
{
dp[j]=max(dp[j],dp[j-i]+a[i]);
}
cout<<dp[S];
return 0;
}
P1510
转化一下,把精力作为价值,然后木石作为物品,然后求出来,需要最少精力,如果满足的话就ok
#include<iostream>
#include<string.h>
using namespace std;
int dp[19977],vv,tl,flag;
int main()
{
int v,n,c;
cin>>v>>n>>c;
for(int i=1;i<=n;i++)///多少块是物品可能性
{
cin>>vv>>tl;
for(int j=c;j>=tl;j--)//这个是体力,也就是背包的价值
{
dp[j]=max(dp[j],dp[j-tl]+vv);//每次都是最少的 ,所以一开始要设置大
}
}
for(int i=1;i<=c;i++)
{
if(dp[i]>=v)
{cout<<c-i;
flag=1;
break;
}
}
if(flag==0)
cout<<"Impossible";
}
P1466
对于这种题目其实也是背包,先求出来价值(也就是各个数字的和)然后物品个数就是一半,然后每一次都是+1
这种初始化得是1哦
//背包能装物品n/2,装物品价值就是他们和
#include<iostream>
using namespace std;
long long int dp[1002]={1};/long long 吞了一个点
int main()
{
int n,m;
cin>>n;
m=(n+1)*n/2;//求和
if(m%2==1)
{
cout<<0;
return 0;
}
for(int i=1;i<=n;i++)//物品
{
for(int j=m/2;j>=i;j--)//价值
{
dp[j]+=dp[j-i];//加这个物品前的结合自己的
}
}
cout<<dp[m/2]/2;
return 0;
}
P1757
分组背包,对于每一次更新其实只能让这个组里面最好的去更新
可以用bag来存储,里面放上物品的体积和价值,还可以放一个w,来统计这个包里到底有多少东西
dp循环里面,最外层是包的数量,然后第二层是它的容积,然后第三层是循环这个i背包里面每个东西放进去,取最大值
#include<bits/stdc++.h>
using namespace std;
struct Bag
{
int a[1010];
int b[1010];
int w;
}c[1001];
int dp[1010];
int main()
{
int M,N,p=0;
cin>>M>>N;
for(int i=1;i<=N;i++)
{
int x,y,z;
cin>>x>>y>>z;
p=max(p,z);
c[z].w++;
c[z].a[c[z].w]=x;
c[z].b[c[z].w]=y;
}
for(int i=1;i<=p;i++)
{
for(int j=M;j>=0;j--)
{
for(int k=1;k<=c[i].w;k++)
{
if(j-c[i].a[k]>=0)
dp[j]=max(dp[j],dp[j-c[i].a[k]]+c[i].b[k]);
}
}
}
cout<<dp[M];
return 0;
}
P1064
每个主件可以有0,1,2个附件,所以就是说对于每个主件就是一个背包,这个背包里面有4种可能性,要把这个存进去
#include<iostream>
using namespace std;
int dp[12345]={0};
struct node
{
int a[10202];
int b[10202];
int w;
}c[10202];
int main()
{
int m,n,p;
cin>>m>>n;
for(int i=1;i<=n;i++)
{
int x,y,z;
cin>>x>>y>>z;
if(z==0)
{
c[i].w=1;
c[i].a[1]=x;
c[i].b[1]=y*x;
}
else
{
if(c[z].w ==1)
{
c[z].w =2;
c[z].a[2] =x+c[z].a[1];
c[z].b[2] =x*y+c[z].b[1];
}
else
{
c[z].a[3]=c[z].a[1]+x;
c[z].b[3]=c[z].b[1]+x*y;
c[z].a[4]=c[z].a [2]+x;
c[z].b [4]=c[z].a [2]+x*y;
c[z].w=4; }
}
}
for(int i=1;i<=n;i++)
{
for(int j=m;j>=0;j--)
{
for(int k=1;k<=c[i].w ;k++)
{
if(j>=c[i].a[k])
dp[j]=max(dp[j],dp[j-c[i].a[k]]+c[i].b[k]) ;
}
}
}
cout<<dp[m];
return 0;
}