【洛谷P1048】采药
01背包,直接套
#include <bits/stdc++.h>
using namespace std;
int dp[1100]={0};
struct me{int time,v;
}a[110];
bool cmp(me a,me b){
if(a.time!=b.time)
return a.time>b.time;
return a.v>b.v;
}
int main() {
int t,n,ans=0;
cin>>t>>n;
for(int i=0;i<n;i++)
cin>>a[i].time>>a[i].v;
sort(a,a+n,cmp);
/*
for(int i=0;i<n;i++)
cout<<a[i].time<<endl;*/
for(int i=0;i<n;i++){
for(int j=t;j>=a[i].time;j--){
dp[j]=max(dp[j],dp[j-a[i].time]+a[i].v);
ans=max(ans,dp[j]);
}
}
cout<<ans;
return 0;
}
【洛谷P1616】疯狂的采药
无限背包,所以比起上边这个要从v最小开始循环。
然后把各个量改成合适的,比如longlong
#include <bits/stdc++.h>
using namespace std;
long long dp[10000010]={0};
struct me{int time,v;
}a[10010];
bool cmp(me a,me b){
if(a.time!=b.time)
return a.time>b.time;
return a.v>b.v;
}
int main() {
long long ans=0,t,n;
cin>>t>>n;
for(int i=0;i<n;i++)
scanf("%d%d",&a[i].time,&a[i].v);
sort(a,a+n,cmp);
/*
for(int i=0;i<n;i++)
cout<<a[i].time<<endl;*/
for(int i=0;i<n;i++){
for(long long j=a[i].time;j<=t;j++){
dp[j]=max(dp[j],dp[j-a[i].time]+a[i].v);
ans=max(ans,dp[j]);
}
}
printf("%lld",ans);
return 0;
}
【洛谷P1049】装箱问题
因为没有给出“价值”这一指标所以把体积当成dp[j]的值,多少有点微妙但还真就这样。
#include <bits/stdc++.h>
using namespace std;
int dp[20100]={0};
int a[1000];
int main() {
int v,n,ans=0;
cin>>v>>n;
for(int i=0;i<n;i++)
cin>>a[i];
sort(a,a+n);
/*
for(int i=0;i<n;i++)
cout<<a[i].time<<endl;*/
for(int i=n-1;i>=0;i--){
for(int j=v;j>=a[i];j--){
dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
ans=max(dp[j],ans);
}
}
cout<<v-ans;
return 0;
}
【洛谷P1833】樱花
显然,这一道题重点是把最大可看的次数用二的幂表示。
但重点是当次数给了0时是表示无限,在写完一大堆特判后发现题解佬巧妙的利用t<1000这个条件,把这种情况下的次数改成一个够大的数,妙啊。
#include <bits/stdc++.h>
using namespace std;
int dp[2000010]={0};
int t[10010],num[10010],c[10010];
int tt[200100],cc[200100];
int main() {
int hs,ms,he,me,time,n,ans=0;
scanf("%d:%d%d:%d",&hs,&ms,&he,&me);
cin>>n;
time=(he-hs)*60+me-ms;
//cout<<time<<endl;
for(int i=0;i<n;i++){
cin>>t[i]>>c[i]>>num[i];
if(num[i]==0)num[i]=65535;
}
int j=0;
for(int i=0;i<n;i++){
int temp=1;
while(temp<=num[i]){
tt[j]=t[i]*temp;
cc[j]=c[i]*temp;
num[i]-=temp;
temp*=2;
//cout<<tt[j]<<" "<<cc[j]<<endl;
j++;
}
if(num[i]!=0){
tt[j]=t[i]*num[i];
cc[j]=c[i]*num[i];
//cout<<tt[j]<<" "<<cc[j]<<endl;
j++;
}
}
for(int i=0;i<j;i++){
for(int k=time;k>=tt[i];k--)
dp[k]=max(dp[k],dp[k-tt[i]]+cc[i]);
}
for(int i=tt[j-1];i<=time;i++)
ans=max(ans,dp[i]);
cout<<ans;
return 0;
}