1. 程式人生 > >HDU-1864&&HDU-2602(01背包問題)

HDU-1864&&HDU-2602(01背包問題)

ret open pan esp 例題 技術分享 cto mem iostream

DP-01背包問題例題

輸入處理有點惡心人,不過處理完後就是簡單的DP了

從頭開始dp[i]表示從0開始到i的最優結果,最後從都邊裏dp數組,求得最大的報銷額。

對於每個i都要從頭維護最優結果。(二刷感覺仍不得dp精髓,,,,)

HDU-1864最大報銷額

技術分享圖片
 1 #include <iostream>
 2 #include <queue>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <cstring>
 7 #include <queue>
 8
#include <map> 9 #include <vector> 10 #define INF 0x3f3f3f3f 11 #define FRE() freopen("in.txt","r",stdin) 12 13 using namespace std; 14 typedef long long ll; 15 const int maxn = 500; 16 double dp[maxn]; 17 double money,a[maxn]; 18 19 bool judge(char op) 20 { 21 if(op==A||op==B||op==
C) 22 return true; 23 return false; 24 } 25 26 27 void init(int n,int& index) 28 { 29 char op,ch; 30 while(n--) 31 { 32 int x,ok = 1; 33 double tmp,sumA = 0,sumB = 0,sumC = 0; 34 cin>>x; 35 for(int i = 0; i<x; i++) 36 { 37 cin>>ch>>op>>tmp;
38 if(judge(ch)) 39 { 40 if(ch==A)sumA += tmp; 41 if(ch==B)sumB += tmp; 42 if(ch==C)sumC += tmp; 43 } 44 else 45 ok = 0; 46 } 47 if(ok && (sumA<=600.0 && sumB<=600.0 && sumC<=600.0 && (sumA+sumB+sumC) <=1000.0)) 48 a[index++] = (sumA+sumB+sumC)*100.0; 49 } 50 return; 51 } 52 53 54 int main() 55 { 56 int n,index = 0,in; 57 while(cin>>money>>n) 58 { 59 if(n==0)break; 60 index = 0; 61 memset(a,0,sizeof(a)); 62 init(n,index); 63 // for(int i = 0; i<index; i++) 64 // { 65 // cout<<a[i]<<" "; 66 // } 67 // cout<<endl<<endl; 68 memset(dp,0,sizeof(dp)); 69 in = 1; 70 for(int i = 0; i<index; i++)//枚舉每一個可以報銷的票 71 { 72 for(int j = 0; j<=i; j++) 73 { 74 if(dp[j]+a[i] <= money*100.0) 75 { 76 dp[i] = max(dp[i],dp[j]+a[i]);//每一個票的位置上對應一個dp維護該位置上的最大報銷額度 77 } 78 } 79 } 80 double ans = 0; 81 for(int i = 0; i<index; i++) 82 { 83 ans = max(ans,dp[i]); 84 } 85 printf("%.2f\n",ans/100.0); 86 } 87 return 0; 88 }
View Code

HDU-2602 Bone Collector

01背包問題的板子問題

做這個題的時候嘗試了紫書上講的滾動數組;

技術分享圖片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 
 5 using namespace std;
 6 const int maxn = 1005;
 7 int N,V;
 8 int wet[maxn],val[maxn];
 9 int dp[maxn];
10 
11 int main()
12 {
13     //freopen("in.txt","r",stdin);
14     int T;
15     scanf("%d",&T);
16     while(T--)
17     {
18         memset(wet, 0, sizeof(wet));
19         memset(val, 0, sizeof(val));
20         memset(dp, 0, sizeof(dp));
21         scanf("%d%d",&N,&V);
22         for(int i = 0; i < N; i++)
23             scanf("%d",&val[i]);
24         for(int i = 0; i < N; i++)
25             scanf("%d",&wet[i]);
26         for(int i = 0; i < N; i++)//枚舉每一塊骨頭
27         {
28             for(int j = V; j >= 0; j--)//枚舉背包體積區間的每一個大小
29             {
30                 if(j >= wet[i])//如果背包體積大於骨頭的體積
31                     dp[j] = max(dp[j], dp[j - wet[i]] + val[i]);//更新該體積所能裝下的最大的價值
32             }
33         }
34         printf("%d\n",dp[V]);
35     }
36     return 0;
37 }
View Code

HDU-1864&&HDU-2602(01背包問題)