Codeforces 294B Shaass and Bookshelf:dp

题目链接: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 }

 

posted @ 2018-01-08 17:33  Leohh  阅读(401)  评论(0编辑  收藏  举报