POJ3276
来源:互联网 发布:次声波软件 编辑:程序博客网 时间:2024/06/06 05:35
/*POJ3276有N张牌 正面朝上记为1 反面朝上记为0 每张牌都是正面或反面朝上设置一个数K 当每次翻牌时 翻K张连续的牌 请求出 为了让所有的牌反面朝上的最小操作次数M和对应的K N∈[1,5000] EG:输入N=7 1101011 输出 K=3 N=3 (先反转1--3牌 再反转3--5 再反转5--7)解:如果把牌的方向01便历搜索则需要2^N次方 N比较大的时候是无法求解的 需要改变方式 首先 对相同的一个区间进行多次反转是多余的 通过观察 还会发现 交换区间的反转顺序是对结果没有影响的 因为 对每个牌来说 一个个体翻多少次是固定的 且只有0--1两种状态 就像上面的例子 也可以 先反转3--5牌 再反转1--3 再反转5--7 一样的效果 于是 我们想办法求出需要反转的区间的集合会方便一些 区间!!! 先考虑最左边的牌 无论K为何值 包含这张牌的区间只有一个,如果这张牌正面 我们就会知道 包含这张牌并且以这张牌为首的区间是不需要反转的。 否则进行反转 当这张牌变为1之后 再考虑右侧区间 问题规模减少了1 不断地重复下去 就可以不用一一搜索求反转次数了 对于K 并不需要对所有的K都求一遍,这个地方有待化简 也是降低时间复杂度的重要地方 设F[i]=对区间[i,i+K-1]进行了一次反转 翻转了的话为1 没有反转记为0 先考虑一下下面的问题 如果K=3 下方的数轴中 最左边的牌为数轴上的1 Q是第五张牌 那么包含连续的K=3张牌 且包含Q的区间F[?] 有 F[3,3+3-1] F[4,4+3-1] F[5,5+3-1] 三种 其中这三个F[ ]中的前两个和Q之前的牌的状况有关 而F[5,5+3-1]是与前两个有关的 因为F[3,3+3-1] F[4,4+3-1] 的反转与否 都决定了F[5,5+3-1]是否要进行反转 Q |____|____|____|____|____|____|____|_________>F 1 2 3 4 5 6 7 8 回到F 对于第i张牌 ______________________________________| i-1 || ∑ F[j] j范围 i-K+1 --> i-1|| j=i-k+1 ||_____________________________________|如果∑F[j]为奇数 则这张牌的方向与最开始的方向是相反的否则方向没变又有________________________________________________| i i-1 || ∑ F[j] = ∑ F[j]+F[i]-F[i-K+1] || j=(i+1)-k+1 j=i-K+1 ||______________________________________________|这样就可以用常数的时间求出来K 的情况下需要反转的次数动态规划 代码:*/# include <stdio.h># define MAX 5001 int KKK(char S[],int N,int K);//返回K的情况下的反转次数int main(){ int K,M,N,k,m;char S[MAX]; scanf("%d ",&N);gets(S);//正面朝上记为1 反面朝上记为0M=N; for(K=1;K<=N;K++)//遍历{ m=KKK(S,N,K);if(m>=0&&M>m)//如果当前K满足条件 且次数少{ M=m; k=K;}}printf("K=%d M=%d\n",k,M); return 0;}int KKK(char S[],int N,int K)//返回K的情况下的反转次数{ int F[MAX]={0},sum=0,count=0,i;//sum动态计算∑F[i] for(i=0;i<=N-K;i++)//计算区间F[i,i-K+1] { if((S[i]-48+sum)%2)//如果前面的牌经过了 "S[i]"+sum次转变+此牌原本的状态 后 此牌现状还是在正面 { count++;//此时加一反转 F[i]=1;//做标记 } sum+=F[i];//更新反转次数 if(i-K+1>=0)//为了防止数组越界 因为i-K+1不一定>=0 sum-=F[i-K+1]; } for(i=N-K+1;i<N;i++)//检测前N-K张牌反转后 剩下的牌中是否有不符合条件的 { if((S[i]-48+sum)%2)//一旦检测到 说明这种情况下不符合 return -1; if(i-K+1>=0)//更新sum sum-=F[i-K+1]; } return count;}
附加:
▲ABC中∠A∈[60°,90°],则∠A取得最大角的概率为?计算机求概率
我很喜欢数学,在高中的时候想过很多题 也对一些数学故事感兴趣 记得当时看正17边形的证明和画法看了整整两天才看明白。。。然后自己画了几个才满意。
当时在上高中的时候,有一道题是这样说的:
有一根细长木棒长为L,随机切两下,则能组成一个三角形的概率为多少?
解法使用的 设边A=X,边B=Y根据三角形的任意两边之和大于第三边的不等式画图 解得P=0.25
我大二学概率论时突然间想出了一道题,可是却没办法解答。
就是标题中的那道题
我问了老师和学长 自己也一直在想 然后我就用了电脑的方法编了个程序:
# include <time.h># include <stdio.h># include <stdlib.h># define N 40000int main(){long double A[3][N]={0},sum=0,MAX;int i; srand(time(NULL)); for(i=0;i<N;i++) { A[0][i]=rand()%30+60+0.000000001*(rand()%100000000); A[1][i]=rand()%(180-int(A[0][i]))+0.000000001*(rand()%100000000); MAX=(A[0][i]>A[1][i]?A[0][i]:A[1][i]); A[2][i]=180.0-A[1][i]-A[0][i]; MAX=(A[2][i]>=MAX?A[2][i]:MAX); if(MAX==A[0][i]) sum++; } printf("%lf",sum*1.0/N); return 0;}
毕竟使用计算机的随机数模拟的 大部分结果都是在0.439左右
经过一星期的思考 我的到了这个问题的解答案是3/7≈0.428:
如果程序没问题的话结果也应该是0.428左右 不清楚为什么会多0.01左右
1 0
- POJ3276
- POJ3276
- poj3276 翻转
- 开关问题-poj3276
- POJ3276---The Cow Lexicon
- poj3276(开关问题)
- POJ3276 The Cow Lexicon
- poj3276(开关问题)
- poj3276 Face the Right Way
- POJ3276-Face The Right Way
- POJ3276-Face The Right Way
- POJ3276-Face The Right Way
- POJ3276 Face The Right Way
- poj3276 Face The Right Way
- POJ3276——开关问题
- poj3276:Face The Right Way
- poj3276 Face The Right Way模拟
- POJ3276 Face The Right Way 【尺取法】
- 简单的获取Android手机屏幕的像素
- 天梯赛练习 是否完全二叉搜索树
- 北京阿凡达雪景
- replica character liquid crystal display control
- 从零开始学习EasyDarwin(RTSP连接监听初始化)
- POJ3276
- 素数的判断方法
- 从新建vue项目到引入组件Element流程
- Package.json配置相关知识
- 深入解析spring中用到的九种设计模式
- laravel路由和路由组
- IO-异常、File、递归
- Java异常处理和设计
- linux关于bashrc与profile的区别(转)