首页 > 代码库 > [HAOI2012]音量调节
[HAOI2012]音量调节
题目链接
吐槽-没看到可以调大调小,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]音量调节
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。