码迷,mamicode.com
首页 > 其他好文 > 详细

[HAOI2012]音量调节

时间:2017-06-03 23:24:19      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:tar   event   ons   吐槽   pen   class   return   ==   bsp   

题目链接

吐槽-没看到可以调大调小,WA了一小时。很伤心,所以在此希望大家记得仔细读题!!!

思考

01背包问题是 一个物品拿或者不拿中求最大值的问题

这道题目就是 音量增加或者减少中求最大值的问题

但是如果生搬硬套01背包的方程用在这里肯定是不合适的。

在这里,我们想对于每次调节,也就是两种可能 在上次的基础上调大,或者是调小。但是调大不能超过上限,调小不能超过下限。

让我们再分析分析样例:

3 5 10

5 3 7

第一次调节 只能从 5开始 调小的话就是0 调大的话就是10

第二次调节 先分析0 调小不可以 调大只能是3  在分析10 调小是7 调大不可以

第三次调节 先分析3 调小不可以 调大是10 再分析7 调小是0 调大是不可以

是不是隐隐约约能摸索出这个转移方程了?

对没错,方程是 用二维bool型数组来DP,f[i][j]=true表示第i首歌音量为j可行,DP方程为:

if((f[i-1][j+c[i]]==true&&j+c[i]<=maxL)||(f[i-1][j-c[i]]==true&&j-c[i]>=0)) f[i][j]=true;

关键是f[i-1][j+c[i]] 和 f[i-1][j-c[i]]这两个,要仔细推敲。

初始值f[0][初始值]=1

最后再从大到小遍历 最后一次 调节时的最大值,如果存在输出。如果不存在则输出-1.

技术分享
 1 #include <cstdio>
 2 const int maxn=1005;
 3 int n,m,MAX,c[maxn];
 4 bool dp[maxn][maxn];
 5 int main(){
 6     scanf("%d%d%d",&n,&m,&MAX);
 7     for(int i=1;i<=n;i++) scanf("%d",&c[i]);
 8     dp[0][m]=1;
 9     for(int i=1;i<=n;i++)
10         for(int j=0;j<=MAX;j++){
11             if( (dp[i-1][j+c[i]] && j+c[i]<=MAX) || ( dp[i-1][j-c[i]] && j-c[i]>=0)) 
12             dp[i][j]=1;
13         }
14     for(int i=MAX;i>=0;i--){
15         if(dp[n][i]) {
16             printf("%d\n",i);
17             return 0;
18         }
19     }
20     printf("-1");
21     return 0;
22 }
代码实现

 

[HAOI2012]音量调节

标签:tar   event   ons   吐槽   pen   class   return   ==   bsp   

原文地址:http://www.cnblogs.com/OIerLYF/p/6938723.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!