sgu256 dp

题意: 有一个做气球的机器。 现在想要做m个气球(m<=100), 一共有n个人(n<=10)可以做气球,每个人一分钟可以做fi个, 但是做完之后必须休息ti分钟,现在想要求出最少需要多少分钟可以做完这m个气球。

 

思路:  这道题开始的时候想了很多东西都是不对的。  主要是思路受干扰了。 

这道题可以用dp, dp是这样的。dp[n][i][j][k][r]表示在第i秒结束时用的是第i个人, 上一秒用的是第j个人,以此类推。

这样就可以进行转化了。 这道题有一个很明显的特点就是数据量比较小。 所以可以维护一些可以处理小数据的东西。

其实上次的连连看的题目和这道题又很想的地方。

AC代码:

View Code
 1 #include <cstdio>
 2 #include <iostream>
 3 #include <string>
 4 #include <cstring>
 5 using namespace std;
 6 const int N = 505;
 7 int dp[N][11][11][11][11];
 8 
 9 struct hh
10 {
11     int f, t;
12 } p[N];
13 int n, m;
14 
15 void init()
16 {
17     for(int i=1; i<=n; i++)
18         scanf("%d%d", &p[i].f, &p[i].t);
19     p[0].t = 0;
20     for(int i=0; i<N; i++)
21      for(int i1=0; i1<=10; i1++)
22       for(int i2=0; i2<=10; i2++)
23        for(int i3=0; i3<=10; i3++)
24         for(int i4=0; i4<=10; i4++)
25          dp[i][i1][i2][i3][i4] = -1000;
26     dp[0][0][0][0][0] = 0;
27 }
28 
29 void solve()
30 {
31     bool used[12];
32     int ans = N;
33     for(int i=0; i<N; i++)
34     {
35         for(int i1=0; i1<=n; i1++)
36         {
37             for(int i2=0; i2<=n; i2++)
38             {
39                 for(int i3=0; i3<=n; i3++)
40                 {
41                     for(int i4=0; i4<=n; i4++)
42                     {
43                         if(dp[i][i1][i2][i3][i4] >= m)
44                         {
45                             printf("%d\n", i);
46                             return ;
47                         }
48                         if(p[i2].t <= 1 && i2 != i1)
49                             {
50 
51                                 dp[i+1][i2][i1][i2][i3] = max(
52                                  dp[i+1][i2][i1][i2][i3], dp[i][i1][i2][i3][i4]+p[i2].f);
53                             }
54                         if(p[i3].t <= 2 && i3!=i1 && i3 != i2)
55                             {
56 
57                                 dp[i+1][i3][i1][i2][i3] = max(
58                                  dp[i+1][i3][i1][i2][i3], dp[i][i1][i2][i3][i4]+p[i3].f);
59                             }
60                         if(p[i4].t <= 3 && i4!=i1 && i4!=i2 && i4!=i3)
61                             {
62 
63                                 dp[i+1][i4][i1][i2][i3] = max(
64                                  dp[i+1][i4][i1][i2][i3], dp[i][i1][i2][i3][i4]+p[i4].f);
65                             }
66                         memset(used,0,sizeof(used));
67                         used[i1]=used[i2]=used[i3]=used[i4] = 1;
68                         used[0] = 0;
69                         for(int j=0; j<=n; j++)
70                          {
71                              if(used[j]) continue;
72                              dp[i+1][j][i1][i2][i3] = max(
73                                  dp[i+1][j][i1][i2][i3], dp[i][i1][i2][i3][i4] + p[j].f);
74                          }
75                     }
76                 }
77             }
78         }
79     }
80 }
81 
82 int main()
83 {
84     while(scanf("%d%d", &m, &n) != EOF)
85     {
86         init();
87         solve();
88     }
89     return 0;
90 }

 

 

 

posted @ 2012-10-05 20:48  Gu Feiyang  阅读(408)  评论(0)    收藏  举报