LightOJ1017 Brush (III)(DP)

题目大概说一个平面上分布n个灰尘,现在要用一个宽w的刷子清理灰尘:选择一个起点,往水平线上扫过去这个水平线上的灰尘就消失了。问最多进行k次这样的操作能清理最多多少灰尘。

没什么的DP。

  • 先按垂直坐标给灰尘们排个序,
  • 然后d[i][k]表示前i个灰尘中,进行到第k次清理操作时刷子底部在第i个灰尘的竖坐标能清理的最多灰尘,
  • 最后转移一个一个往前枚举就OK了,规模很小。
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 int d[111][111];
 6 int main(){
 7     int t,n,w,K,x[111],y;
 8     scanf("%d",&t);
 9     for(int cse=1; cse<=t; ++cse){
10         scanf("%d%d%d",&n,&w,&K);
11         for(int i=0; i<n; ++i){
12             scanf("%d%d",&y,x+i);
13         }
14         sort(x,x+n);
15         memset(d,0,sizeof(d));
16         d[0][1]=1;
17         int res=1;
18         for(int i=1; i<n; ++i){
19             int cnt=1;
20             for(int k=0; k<i; ++k){
21                 if(x[i]-x[k]<=w){
22                     ++cnt;
23                 }
24             }
25             d[i][1]=cnt;
26             res=max(res,d[i][1]);
27             for(int j=2; j<=K; ++j){
28                 int mx=0;
29                 for(int k=0; k<i; ++k){
30                     if(x[i]-x[k]<=w){
31                         break;
32                     }
33                     mx=max(mx,d[k][j-1]);
34                 }
35                 if(mx!=0){
36                     d[i][j]=mx+d[i][1];
37                     res=max(res,d[i][j]);
38                 }
39             }
40         }
41         printf("Case %d: %d\n",cse,res);
42     }
43     return 0;
44 }

 

posted @ 2016-07-09 16:35  WABoss  阅读(171)  评论(0编辑  收藏  举报