背包dp
#include<bits/stdc++.h> using namespace std; const int N=4e3+10; int dp[N],v[4]; //dp[i]表示长度 为i最多能够分成几段 int main(){ int n; cin>>n>>v[0]>>v[1]>>v[2]; for(int i=0;i<=n;i++){ for(int j=0;j<3;j++){ if(i==v[j]||(i>v[j]&&dp[i-v[j]])){ //状态转移方程 dp[i]=max(dp[i],dp[i-v[j]]+1); } } } cout<<dp[n]<<endl; }
樱花(多重背包,二进制拆分)
经典多重背包
#include<bits/stdc++.h> using namespace std; const int N=1e6+10,M=2e4+10; int v[N],w[N],s[N],ww[N],vv[N],cnt,n; int dp[M]; void init(){ for(int i=1;i<=n;i++){ int k=1; while(s[i]){ cnt++; vv[cnt]=k*v[i]; ww[cnt]=k*w[i]; s[i]-=k; k*=2; if(s[i]<k){ cnt++; vv[cnt]=v[i]*s[i]; ww[cnt]=s[i]*w[i]; break; } } } } int main(){ int h1,m1,h2,m2; scanf("%d:%d %d:%d",&h1,&m1,&h2,&m2); int t=(h2-h1)*60+m2-m1; cin>>n; for(int i=1;i<=n;i++){ cin>>v[i]>>w[i]>>s[i]; if(s[i]==0)s[i]=t/v[i]; } init(); for(int i=1;i<=cnt;i++){ for(int j=t;j>=vv[i];j--){ dp[j]=max(dp[j],dp[j-vv[i]]+ww[i]); } } cout<<dp[t]<<endl; }

浙公网安备 33010602011771号