01揹包入門

2021-07-02 22:20:43 字數 4590 閱讀 7183

01揹包問題模型:

有n件物品和乙個容量為v的揹包。第i件物品的費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可使價值總和最大。

這是最基礎的揹包問題,特點是:每種物品僅有一件,可以選擇放或不放。

用子問題定義狀態:即f[i][v]表示前i件物品恰放入乙個容量為v的揹包可以獲得的最大價值。則其狀態轉移方程便是:

f[i][v]=max

hdu 2546

因為餘額大於等於5元 就可以購買任何**的物品 

所以我們可以預留5元來購買最貴的物品 其他的錢使用01揹包 去得到最大的價值

#include #include #include #include #include #include #include #include #include #define mem(a,x) memset(a,x,sizeof a)

#define eps 1e-8

#define mod 10009

#define maxn 10010

#define maxm 100010

#define inf 99999999

#define ll __int64

#define bug cout<<"here"<'9') c = getchar();

int x = 0;

while (c >= '0' && c <= '9')

return x;

}void print(int a)

int price[maxn],dp[maxn];

int main()

}printf("%d\n",m+5-dp[m]-price[n-1]);

}return 0;

}

hdu 2602

裸的01揹包

#include #include #include #include #include #include #include #include #include #define mem(a,x) memset(a,x,sizeof a)

#define eps 1e-8

#define mod 10009

#define maxn 1010

#define maxm 100010

#define inf 99999999

#define ll __int64

#define bug cout<<"here"<'9') c = getchar();

int x = 0;

while (c >= '0' && c <= '9')

return x;

}void print(int a)

int val[maxn],vol[maxn];

int dp[maxn];

int main()

}printf("%d\n",dp[v]);

}return 0;

}

hdu 2639

題意在上一題的基礎上 增加了 求第k大

#include #include #include #include #include #include #include #include #include #define mem(a,x) memset(a,x,sizeof a)

#define eps 1e-8

#define mod 10009

#define maxn 1010

#define maxm 100010

#define inf 99999999

#define ll __int64

#define bug cout<<"here"<'9') c = getchar();

int x = 0;

while (c >= '0' && c <= '9')

return x;

}void print(int a)

struct node

no[maxn];

int dp[maxn][35];

int a[maxn],b[maxn];

int main()

int x,y,z;

x=y=z=1;

a[k+1]=b[k+1]=-1;

while(z<=k&&(x<=k||y<=k))//迴圈找出第k優解

else

if(dp[j][z]!=dp[j][z-1])

z++;}}

}printf("%d\n",dp[v][k]);

}return 0;

}

hdu 2955

有乙個可以接受的被抓概率p 有n家銀行可以去盜竊

下面分別給出每家銀行可以盜竊的錢和被抓的概率

因為只有不被抓盜竊的錢才會算 所以我們需要將被抓的概率p 轉化為不被抓的概率1-p

使用01揹包的想法 去計算盜竊相應的銀行不被抓的概率

如果概率大於1-p則是可行的 

#include #include #include #include #include #include #include #include #include #define mem(a,x) memset(a,x,sizeof a)

#define eps 1e-8

#define mod 10009

#define maxn 10010

#define maxm 100010

#define inf 99999999

#define ll __int64

#define bug cout<<"here"<'9') c = getchar();

int x = 0;

while (c >= '0' && c <= '9')

return x;

}void print(int a)

struct node

no[maxn];

double dp[maxn];

int main()

}for(int i=sum;i>=0;i--)}}

return 0;

}

hdu 3466

如果手上的錢少於qi 則不能進行購買

另外 我們考慮 如果現在有兩個物品 相應的p1,q1,p2,q2

如果先買a後買b 則要求至少有p1+q2 如果先買b後買a 則要求至少有p2+q1

如果在先買a的情況下較優 則p1+q2q2-p2

所以需要按q-p的值由大到小排序  這樣解決後效性的問題

#include #include #include #include #include #include #include #include #include #define mem(a,x) memset(a,x,sizeof a)

#define eps 1e-8

#define mod 10009

#define maxn 10010

#define maxm 100010

#define inf 99999999

#define ll __int64

#define bug cout<<"here"<'9') c = getchar();

int x = 0;

while (c >= '0' && c <= '9')

return x;

}void print(int a)

struct node

}printf("%d\n",dp[m]);

}return 0;

}

hdu 1864

給出報銷額度 n張發票

每張發票只能報銷abc三類  每類的不能超過600元  每張總的不能超過1000元

先處理出 所有發票中能夠報銷的金額  剩下的就是用01揹包的思想求出最大報銷金額

#include #include #include #include #include #include #include #include #include #define mem(a,x) memset(a,x,sizeof a)

#define eps 1e-8

#define mod 10009

#define maxn 3000010

#define maxm 100010

#define inf 99999999

#define ll __int64

#define bug cout<<"here"<'9') c = getchar();

int x = 0;

while (c >= '0' && c <= '9')

return x;

}void print(int a)

int dp[maxn];

int money[40];

int main()

}double ans=dp[sum]*1.0/100.0;

printf("%.2lf\n",ans);

}return 0;

}

01揹包入門

description 乙個旅行者有乙個最多能裝m公斤的揹包,現有n件物品,它們的重量分別是w1,w2,w3,wn,它們的價值分別為c1,c2,c3,cn。若每種物品只有一件,求旅行者能獲得的最大總價值。input m,和n m 200,n 30 接下來共n行每行兩個整數wi,ci output 最...

0 1揹包入門

有n個重量分別為w1 w2 w3 w4 wn的物品,編號1 n,它們的價值為v1 v2 v3 v4 vn。現有一容量為w的揹包,求盡可能的把揹包裝滿並使價值最大 下面不妨以 為例 物品編號 重量價值15 4234 3234 11思路大概是用蠻力法找出n的所有冪集,然後遍歷一遍,找到最優解 複雜度為o...

01揹包 DP入門

n個重量和價值分別為w,v的物品。找出總重量不超過w 的物品,求所有挑選方案中價值總和的最大值。n 4 w,v w 5 輸出 7 選0號,1號,3號 理解 n個物品 揹包容量w int w max n v max n weight,value 暴搜 o 2 n int rec int i,int j...