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...