UESTC 606(原1707) Alice's Piano(DP+贪心)

本文介绍了一个关于特殊钢琴演奏的问题,钢琴拥有两排键盘且演奏方式独特。通过动态规划与贪心算法结合的方法来解决演奏者如何按特定规则完成演奏的问题,并给出具体的实现代码。

Description

Alice has a piano which can plays nice music, but it's different from other pianos. It has two rows of keys, and the method of playing it is also quite special. When Alice plays piano, she has to put her two hands on the leftside of the two rows of keys respectively (without touching the leftmost keys of the two rows). And then her hands move on the keys from left to right one by one. Each time she can move one of her hands by one key, either on the above row or the below row. She has to keep the difference between the number of black keys and white keys she has already touched no more than K to make sure the music is beautiful. When the music is end, her two hands should be both on the rightmost of the piano keyboard. Now Alice wants to know whether she can play nice music, given the description of the piano.
Suppose the number of keys of the two rows are both N. And two strings are given to describe the keyboard. “1” stands for black keys while “0” for white ones.

Input 

There are multiple cases, end by EOF.
For each case, the first line contains two integers N(3 <= N <= 1000) and K (0 <= K <= 1000), with two 0-1 strings which are described above.

Output 

If she can play the music, please output an answer string of length 2N which has the minimum lexicographic order. In the answer string, “1” represents move on the above row while “2” represents the below row. If she cannot, just output "Poor Alice".

Sample Input 

4 1
0011
0110

4 1
1100
1100

Sample Output 

22121112
Poor Alice

Hint 

Take the first sample for explaining:
Suppose Alice puts her left hand on the above row of keys, and right on the
below one, the answer string stands for the following process:
1. move right hand to the 1st key of the below row of keys.
2. move right hand to the 2nd key of the below row of keys.
3. move left hand to the 1st key of the above row of keys.
4. move right hand to the 3rd key of the below row of keys.
5. move left hand to the 2nd key of the above row of keys.
6. move left hand to the 3rd key of the above row of keys.
7. move left hand to the 4th key of the above row of keys.
8. move right hand to the 4th key of the below row of keys.

Source 

6th BUPT Programming Contest Final

 

动态规划,DP找出能到达最终状态的状态,然后进行贪心选择,能选1则选1

 1 #include <cstdio>  
 2 #include <cstring>  
 3 #define MAXN 1010  
 4 #define INF 0x7fffffff  
 5      
 6 int i,j,n,k,x,y;  
 7 int dp[MAXN][MAXN];  
 8 char s1[MAXN],s2[MAXN];  
 9      
10 int abs(int x)  
11 {  
12     if(x>=0) return x;  
13     else return -x;  
14 }  
15      
16 void readstring()  
17 {  
18     scanf("%s",&s1[1]);  
19     scanf("%s",&s2[1]);  
20     int i;  
21     for(i=1;i<=n;++i)  
22     {  
23         if(s1[i]=='1') ++dp[n][n];  
24         else --dp[n][n];  
25         if(s2[i]=='1') ++dp[n][n];  
26         else --dp[n][n];  
27     }  
28 }  
29      
30 int main()  
31 {  
32     while(scanf("%d%d",&n,&k)!=EOF)  
33     {  
34         memset(dp,0,sizeof(dp));  
35         readstring();  
36         for(i=n;i>=0;--i)  
37             for(j=n;j>=0;--j)  
38             {  
39                 if(i==n && j==n) continue;  
40                 dp[i][j]=k+1;  
41                 if(i!=n && abs(dp[i+1][j])<=k)  
42                 {  
43                     dp[i][j]=dp[i+1][j];  
44                     if(s1[i+1]=='1') --dp[i][j];  
45                     else ++dp[i][j];  
46                 }  
47                 else if(j!=n && abs(dp[i][j+1])<=k)  
48                 {  
49                     dp[i][j]=dp[i][j+1];  
50                     if(s2[j+1]=='1') --dp[i][j];  
51                     else ++dp[i][j];  
52                 }  
53             }  
54         if(dp[0][0]>k) {printf("Poor Alice\n");continue;}  
55         else
56         {  
57             x=y=0;  
58             while(x<n || y<n)  
59             {  
60                 if(x<n && abs(dp[x+1][y])<=k) {printf("1");++x;}  
61                 else {printf("2");++y;}  
62             }  
63             printf("\n");  
64         }  
65     }  
66 }
View Code

 

转载于:https://www.cnblogs.com/oyking/archive/2013/06/04/3116594.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值