題目連結:http://codeforces.com/problemset/problem/294/B
題意:
有n本書,每本書的厚度為t[i],寬度為w[i] (1<=t[i]<=2, 1<=w[i]<=100)。
然後讓你將所有書按照下面的方式擺放:
在下面放一本書會佔用下面t[i]的長度。
在上面放一本書會佔用上面w[i]的長度。
最終要保證上面的總長度不超過下面的總長度。
問你下面的總長度最小是多少。
題解:
表示狀態:
dp[i][j] = min length
表示已經放了前i本書,下面的總長度為j時,上面的最小總長度。
找出答案:
ans = min i (dp[n][i]<=i)
如何轉移:
對於第i本書,要麼放上面,要麼放下面。
dp[i][j] = min(dp[i-1][j]+w[i], dp[i-1][j-t[i]])
邊界條件:
set dp = INF
dp[0][0] = 0
AC Code:
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #define MAX_N 105 5 #define MAX_T 205 6 #define INF 1000000000 7 8 using namespace std; 9 10 int n; 11 int t[MAX_N]; 12 int w[MAX_N]; 13 int dp[MAX_N][MAX_T]; 14 15 int main() 16 { 17 cin>>n; 18 for(int i=1;i<=n;i++) 19 { 20 cin>>t[i]>>w[i]; 21 } 22 memset(dp,0x3f,sizeof(dp)); 23 dp[0][0]=0; 24 int tot=0; 25 for(int i=1;i<=n;i++) 26 { 27 tot+=t[i]; 28 for(int j=0;j<=tot;j++) 29 { 30 dp[i][j]=min(dp[i][j],dp[i-1][j]+w[i]); 31 if(j-t[i]>=0) dp[i][j]=min(dp[i][j],dp[i-1][j-t[i]]); 32 } 33 } 34 int ans=INF; 35 for(int i=0;i<=tot;i++) 36 { 37 if(dp[n][i]<=i) ans=min(ans,i); 38 } 39 cout<<ans<<endl; 40 }