51nod3113 涂气球

博客介绍了3113涂气球的问题,Bob为女朋友准备的气球经过多次区间涂色操作后,需要计算每个气球被涂色次数。文章通过输入输出样例和解析说明,提出利用差分数组处理这类离线区间修改操作的解决方案。
摘要由CSDN通过智能技术生成

3113 涂气球

 Bob给他的女朋友准备了n个气球作为生日礼物,不过他觉得这样还是不够有诚意,于是他将n个气球排成一排,从左到右依次编号1,2,3,......,n-1,n。之后Bob准备进行m次涂颜色的操作,每次选择两个数a,b(1<=a<=b<=n),给第a个气球到第b个气球涂一次颜色。

不过m次操作后,Bob已经忘记他给每个气球涂了多少次颜色了,你能帮他算出每个气球被涂过几次颜色吗?

输入

第一行为两个整数n,m. 
接下来的m行,每行包括2个整数a b(1 <= a <= b <= N)。

输出

一行,包括n个整数,第i个数代表第i个气球总共被涂色的次数

数据范围

对于30%的数据:  n,m<=1000
对于60%的数据:  n,m<=50000
对于100%的数据:n,m<=200000

输入样例

输入样例1:
3 3
1 1
2 2
3 3
输入样例2:
3 3
1 1
1 2
1 3
输入样例3:
2 1
1 2

输出样例

输出样例1:
1 1 1
输出样例2:
3 2 1
输出样例3:
1 1

解析:差分数组处理离线的区间修改操作

放代码:


                
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
气球问题,也称为气球戳破问题(Burst Balloons),是一道经典的动态规划问题。 题目描述: 给定一个数组nums,其中nums[i]表示第i个气球的价值。你可以戳破气球i(i从0到n-1),获得nums[left] * nums[i] * nums[right]的价值,其中left和right分别是戳破气球i左侧和右侧的气球的编号。当i被戳破后,left和right就变成相邻的气球。在戳破所有气球之前,你可以任意次地戳破气球。 求最大的价值。 例如,给定数组[3,1,5,8],可能的戳破顺序为1, 3, 0, 2(即先戳破1号气球,再戳破3号气球,然后戳破0号气球,最后戳破2号气球),最大的价值为167。 解题思路: 采用动态规划的思路,设dp[i][j]表示戳破区间[i,j]内的所有气球能得到的最大价值。假设最后戳破的气球是k,则区间[i,j]可以分为三个部分:[i,k-1]、k、[k+1,j]。则dp[i][j]的状态转移方程为: dp[i][j] = max(dp[i][k-1] + nums[i-1]*nums[k]*nums[j+1] + dp[k+1][j]), i<=k<=j 其中,nums[i-1]和nums[j+1]表示戳破气球i-1和气球j+1能得到的价值,因为在区间[i,j]外的气球已经被戳破了。 时间复杂度:O(n^3) 参考代码: class Solution { public: int maxCoins(vector<int>& nums) { int n = nums.size(); nums.insert(nums.begin(), 1); nums.insert(nums.end(), 1); vector<vector<int>> dp(n+2, vector<int>(n+2, 0)); for(int len=1; len<=n; len++) { for(int i=1; i<=n-len+1; i++) { int j = i+len-1; for(int k=i; k<=j; k++) { dp[i][j] = max(dp[i][j], dp[i][k-1] + nums[i-1]*nums[k]*nums[j+1] + dp[k+1][j]); } } } return dp[1][n]; } };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值