部分板子最佳化中...
你好哇,我是flypig114
程式碼裡有變數陣列的註釋,so...不多廢話,直接上正題!
01揹包
無最佳化
#include<bits/stdc++.h>
using namespace std;
#define ll int//為了方便修改型別
const ll N=1000;//輔助定義陣列
ll n,m;//n是揹包容量 m是物品數量
ll v[N], w[N];//v是物品的重量 w是物品的價值
ll i,j,dp[N][N];//輔助計算
int main()
{
//揹包與DP的開始
cin>>n>>m;
for(i=1;i<=m;i++)
{
cin>>v[i]>>w[i];
}
//進行處理
for(i=1;i<=m;i++)
for(j=n;j>=0;j--)
{
if(j>=v[i])
{
dp[i][j]=max(dp[i-1][j-v[i]]+w[i],dp[i-1][j]);
}
else
{
dp[i][j]=dp[i-1][j];
}
}
//結束首戰告捷
cout<<dp[m][n];
return 0;
}
一維陣列最佳化:
#include<bits/stdc++.h>
using namespace std;
#define ll int//為了方便修改型別
const ll N=1e5;//輔助定義陣列
ll n,m;//n是揹包容量 m是物品數量
ll v[N], w[N];//v是物品的重量 w是物品的價值
ll i,j,dp[N];//輔助計算
int main()
{
//難度上升需要新方法
cin>>n>>m;
for(i=1;i<=m;i++)
{
cin>>v[i]>>w[i];
}
//重中之重(好像就這裡改了)
for(i=1;i<=m;i++)
{
for(j=n;j>=0;j--)
{
if(j>=v[i])
{
dp[j]=max(dp[j-v[i]]+w[i], dp[j]);
}
}
}
//可以輸出了
cout<<dp[n];
return 0;
}
更進一步的常數最佳化:
#include<bits/stdc++.h>
using namespace std;
#define ll int//為了方便修改型別
const ll N=1000;//輔助定義陣列
ll n,m;//n是揹包容量 m是物品數量
ll v[N], w[N];//v是物品的重量 w是物品的價值
ll i,j,dp[N],lower,sum;//輔助計算
int main()
{
//還要最佳化
cin>>n>>m;
for(i=1;i<=m;i++)
{
cin>>v[i]>>w[i];
}
//重中之重(這話怎麼這麼熟悉)
for(i=1;i<=n;i++)
{
if(i!=1)
{
sum+=v[i-1];
}
lower=max(m-sum,v[i]);
for(j=n;j>=lower;j--)
{
//if(j>=v[i])
dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
}
}
//趕緊的輸出
cout<<dp[n];
return 0;
}
完全揹包問題:
#include<bits/stdc++.h>
using namespace std;
#define ll int//為了方便修改型別
const ll N=1e5;//輔助定義陣列
ll n,m;//n是揹包容量 m是物品數量
ll v[N], w[N];//v是物品的重量 w是物品的價值
ll dp[N],i,j;//輔助計算
int main(){
cin>>n>>m;
//輸入
for(i=1;i<=n;i++)
{
cin>>v[i]>>w[i];
}
//完全揹包啟動!
for(i=1;i<=n;i++)
{
for(j=0;j<=m;j++)
{
if(j>=v[i])
dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
}
}
//簡簡單單的輸出
cout<<"max="<<dp[m]<<endl;
return 0;
}
多重揹包問題:
無最佳化
#include<bits/stdc++.h>
using namespace std;
#define ll int//為了方便修改型別
const ll N=100000;//輔助定義陣列
ll m,n;//n是揹包容量 m是物品數量
ll v[N],w[N],s[N];//v是物品的重量 w是物品的價值 s是物品的數量。
ll dp[N],i,j,k;//輔助計算
int main()
{
//忘說了輸入順序按需求更改(不會有人真題都不看就套板子吧?)
cin>>m>>n;
for(i=1;i<=m;i++)
{
cin>>w[i]>>v[i]>>s[i];
}
//熟悉的流程
for(i=1;i<=m;i++)
{
for(j=n;j>=v[i];j--)
{
for(k=1;k*v[i]<=j&&k<=s[i];k++)
{
dp[j]=max(dp[j],dp[j-k*v[i]]+k*w[i]);
}
}
}
//結束了?
cout<<dp[n]<<endl;
return 0;
//結束了。
}