DP----cf#336 div2 C D
来源:互联网 发布:抑郁症测试 知乎 编辑:程序博客网 时间:2024/06/06 09:08
http://codeforces.com/contest/608/problem/D
2016-5-9 思路:
C,对于题目先不去想算法:暴力的想法 就是n*n,对于每一个灯塔我都模拟一遍看有多少个被炸掉的T(即多少个被激活),选最小的炸掉的即选最多被激活的!
不难有一种想法: 先设一个数组全部初始化为0,for(int i=n;i>=1;i–) ,对于每一个灯塔,我们记录从后面激活到这个地方炸掉的最少的灯塔num1,然后算激活它炸掉了多少灯塔num2,然后更新他爆炸范围外的第一个灯塔,表示这个灯塔!可能!的最小值是Num1+num2, 即dp[j]=min(dp[j],num1+num2)。 然后一直更新到dp[1] , 就可以得到最少炸掉的灯塔数。 具体实现我没管,我觉得这种想法必然可行,理论AC。 看看题目,发现有个条件没用: 在右边可以选择一个任意位置任意爆炸的T激活(潜台词就是:可以选任意的灯塔开始激活) 所以我们初始化不能为0,而应该对于i, 初始为 (i+1—n 的灯塔都炸掉) ,好了,理论ac完成
D:
题意: 对一个串,每次可摧毁回文串,最少多少步能摧毁整个串,就是祖玛游戏。
有点难 ,哈哈
区间dp;
不会做不会做,等我dp变强再回过头来想吧
一个人在实验室做的这场比赛,被前两题的小错误卡了很久,水了两道题就滚了。
C:
就是说有n个塔,每个塔有一个爆炸范围power,从右到左激活灯塔,若激活一个灯塔则他会把它power范围内的灯塔都炸掉,再激活下一个灯塔。 可以在右边插入一个任何位置任何power的灯塔,求最小的被炸掉的灯塔数。
可以设置dp[i] 代表如果激活灯塔i,则摧毁dp[i]个灯塔。
如此可以知道状态转移方程:
用二分在序列中找到 >=pos[i]-power[i] 的第一个 灯塔=ppos。
dp[i]=dp[ppos-1] + (i-ppos) //之前的一个爆炸数+ i炸掉的灯塔数
//省略头文件pair<int,int> p[1000005];int dp[1000005];int main(){ int n; scanf("%d",&n); for (int i=0;i<n;i++) scanf("%d %d",&p[i].first,&p[i].second); sort(p,p+n); //排序,为了后一步的dp二分 int ans; for (int i=0;i<n;i++){ int pp=lower_bound(p,p+n,make_pair(p[i].first-p[i].second,-1))-p; //找到爆炸之外的第一个灯塔 dp[i]=dp[pp-1]+i-pp; //i-pp则为激活i炸掉的灯塔数 ans=min(ans,n-i-1+dp[i]); } cout<<ans;}
D题 ——-也是一个dp
一开始在想一维的dp , 设置了两个dp[n]。 然而脑容量不够,并没有想出什么好的东西。
想对于i 从0-i中找一个地址pos,形成回文 所以dp[i]=dp[pos-1]+1;
然而对于第三组样例 会出现 144 232 1 “232”夹在中间导致 dp[n-1] 无法与pos=0形成回文。就开始想着条件应该是 num[i]==num[pos] 就可以开始进行dp状态转移,但是当时思维局限在一维上面了,想半天并没有什么卵用。 最后还是去看了下别人的代码,看到别人用二维便有了些了解 。
dp[i][j] 代表 i到j范围内 最小的步数
如果num[i]==num[j]
则比较容易想到: dp[l][r] =dp[l+1][k-1]+dp[k+1][r]
于是 应该想到:先要从dp[i][i] 到dp[i][i+1] 到dp[i][i+n-1] 依次从左到右的更新
所以一开始应该更新
for(int i=0;i< n;i++)
dp[i][i]=1;
然后更新0-1, 1-2,2-3,3-4,…
0-2,1-3, 2-4,3-5…..
0-3, 1-4,2-5…..
0-n-1
为什么这样呢?因为可以让初始化dp[i][j]=dp[i+1][j]+1;
然后进行状态转移。
int num[505];int dp[505][505];int main(){ freopen("1.txt","r",stdin); int n; while(~scanf("%d",&n)){ for(int i=0;i<n;i++) scanf("%d",&num[i]); //mem(dp); int l,r; for(int i=0;i<n;i++) dp[i][i]=1; //从0 开始 达到n ——循环n次, //从0-1 1-2 2-3 3-4 ... // 0-2 1-3 2-5... // 0-n-1 for(int i=0;i<n;i++) for(int j=0;j<n-i;j++){ //j<n-j 是保证 r<n l=j; r=i+j; if (l==r) continue; dp[l][r]=dp[l+1][r]+1; //若是改成dp[l][r]=dp[l][r-1]+1;会错,但是具体错在哪里我也还没有搞清楚 for(int k=l+1;k<=r;k++){ if(num[l]==num[k]){ if(k==l+1) dp[l][r]=min(dp[l][r],1+dp[k+1][r]); else dp[l][r]=min(dp[l][r],dp[l+1][k-1]+dp[k+1][r]); } } } printf("%d\n",dp[0][n-1]); } return 0;}
- DP----cf#336 div2 C D
- CF 162-div2 D 数学+dp
- CF #261 DIV2 A,B,C,D
- CF #269 DIV2 A,B,C,D
- CF #374 div2 C 树状dp
- CF 174(div2) D
- CF 161 div2 D
- CF 189 div2 D
- CF 159 div2 d
- cf.256.div2.D
- cf R327 div2 D
- CF 259div2 D (状态压缩dp)
- CF #287 div2 D The Maths Lecture 数位DP
- CF round 277 (div2) D题 树形dp
- CF 141 Div2 C Fractal Detector(状态压缩DP)
- CF div2 #343 ----C. Famil Door and Brackets dp
- CF#367(Div2)C. Hard problem (DP)
- CF#369(Div2) C. Coloring Trees (DP)
- Ehcache(05)——缓存的查询
- android导出CSV,中文乱码问题
- CentOS安装IPython
- Facebook 闪光效果开源库shimmer的用法
- ssh分页
- DP----cf#336 div2 C D
- 身份证号码验证
- ReentrantLock源码学习
- MFC消息响应机制分析
- Python循环语句
- ArrayBlockingQueue和LinkedBlockingQueue的区别
- iOS Animation开发简单动画
- Bootstrap(4)之表格和表单
- Mybatis3源码分析(19)-Mapper生成过程-示例