codeforces 289B 递推
2015-12-22 01:57
316 查看
【题目链接】
http://codeforces.com/problemset/problem/289/B
【解题报告】
CF round 177 div2.
题目大意,给你一个N*M的矩阵,里面每个元素有一个val,你可以每次对它+d或者-d,问至少需要多少次操作,使得所有元素val相同。如果不可能,输出-1.
这道题做比赛的时候wa了五次。想对了一点,就是给定的n个数一定是模d的剩余相同。但是具体求最少操作的时候,我把元素值相同的点都合并了,然后误以为这其实是一个给定线段上N个点,求所有点到一个点的最小距离的一个题目,然后直接按照中间点是最优解的方法来做了。
但实际上,我没有考虑到,当某个点出现多次是,它的权重就会增加,那么它到别的点的代价就会增大,就不能单纯按线段上的点来考虑了。
所以这道题应当枚举每个点作为最终目标的时候,所需要的总操作数。
维护一个l[i]表示把第i个数左边的数变的都和它相同需要多少操作。
维护一个r[i]同理。
这可以在线性时间内得到。
之后扫一遍l[i]+r[i]即可。
应当说,因为比赛经验实在太少,所以面对构造算法模型的题目会想的很慢,而且极易想错或者忽略一些细节和边界条件。这几次比赛,包括去地大和北航的个人赛都只能过签到题,对稍微需要用点思维的题就会写崩,频频用很复杂的思维或者写很复杂的没必要的算法来想题做题,都体现了这一弱点。之后应当保持做个人赛的频率,提高比赛的感觉和构造能力的提高。
打得差不可怕,可怕的不能遭受挫折不愿正视缺点,妄自菲薄,妄自尊大。这样的道理很简单,却容易当局者迷。
忽然想到《灌篮高手》里,年轻的三井说:“教练,我想打篮球”,十分难过。只有年轻人才会执着于“梦想”,难以放弃的坚持才是对梦想的最重要的诠释。
所以把叹息留在身后,重新上路吧。
【参考代码】
http://codeforces.com/problemset/problem/289/B
【解题报告】
CF round 177 div2.
题目大意,给你一个N*M的矩阵,里面每个元素有一个val,你可以每次对它+d或者-d,问至少需要多少次操作,使得所有元素val相同。如果不可能,输出-1.
这道题做比赛的时候wa了五次。想对了一点,就是给定的n个数一定是模d的剩余相同。但是具体求最少操作的时候,我把元素值相同的点都合并了,然后误以为这其实是一个给定线段上N个点,求所有点到一个点的最小距离的一个题目,然后直接按照中间点是最优解的方法来做了。
但实际上,我没有考虑到,当某个点出现多次是,它的权重就会增加,那么它到别的点的代价就会增大,就不能单纯按线段上的点来考虑了。
所以这道题应当枚举每个点作为最终目标的时候,所需要的总操作数。
维护一个l[i]表示把第i个数左边的数变的都和它相同需要多少操作。
维护一个r[i]同理。
这可以在线性时间内得到。
之后扫一遍l[i]+r[i]即可。
应当说,因为比赛经验实在太少,所以面对构造算法模型的题目会想的很慢,而且极易想错或者忽略一些细节和边界条件。这几次比赛,包括去地大和北航的个人赛都只能过签到题,对稍微需要用点思维的题就会写崩,频频用很复杂的思维或者写很复杂的没必要的算法来想题做题,都体现了这一弱点。之后应当保持做个人赛的频率,提高比赛的感觉和构造能力的提高。
打得差不可怕,可怕的不能遭受挫折不愿正视缺点,妄自菲薄,妄自尊大。这样的道理很简单,却容易当局者迷。
忽然想到《灌篮高手》里,年轻的三井说:“教练,我想打篮球”,十分难过。只有年轻人才会执着于“梦想”,难以放弃的坚持才是对梦想的最重要的诠释。
所以把叹息留在身后,重新上路吧。
【参考代码】
#include<bits/stdc++.h> using namespace std; int N,M,d; int a[10000+10]; int l[10000+10],r[10000+10]; int main() { cin>>N>>M>>d; for( int i=1; i<=N; i++ ) for( int j=1; j<=M; j++ ) { int t=(i-1)*M+j; cin>>a[t]; } sort( a+1,a+1+N*M ); int temp=a[1]; for( int i=1; i<=N*M; i++ ) //检查是否合法 { a[i]-=temp; if( a[i]%d ){ cout<<-1<<endl; return 0; } } for( int i=1; i<=N*M; i++ ) { l[i]=l[i-1]+ (i-1)*( a[i]-a[i-1] )/d; } for( int i=N*M; i>=1; i-- ) { r[i]=r[i+1]+ ( N*M-i )*( a[i+1]-a[i] )/d; } int ans=1e9; for( int i=1; i<=N*M; i++ ) { ans=min( ans, l[i]+r[i] ); } cout<<ans<<endl; return 0; }
相关文章推荐
- Android 较复杂JSON的解析过程
- MySQL 分区表
- node.js实现CURL功能
- Java的jLinqer包介绍
- HTML5学习笔记之HTML5Canvas图像动画的实现
- Python的ORM框架SQLAlchemy
- Linux_IPtables防火墙详解
- 在node.js中使用COOKIE
- 【Beta阶段】第十次Scrum Meeting!!!
- spring-in-action-mvc-helloworld
- 数据结构之线性表顺序结构
- PHP(五)条件分支和顺序流程
- 单词搜索 II
- Python collections.defaultdict 笔记
- Divide and Conquer:Cable Master(POJ 1064)
- 关于Animation组件的一些记录
- centos7安装CDH5.5.0
- nomasp的2015博客之星投票总结
- 连接Oracle与Hadoop(4) Oracle使用OSCH访问Hive表
- SpringMVC+Mybatis框架整合源码 项目 下载 rest websocket html5