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