Codeforces 294B Shaass and Bookshelf:dp

Leohh發表於2018-01-08

題目連結: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 }

 

相關文章