2018/4/17双线程dp、多边形面积求法、N阶乘最后非零位、博弈(今天本来的博客)

原创 2018年04月17日 21:16:37

NYOJ712探索宝藏这个题就是一个典型的双线程的dp

首先,假设出发点为A 终点为B 那么,根据题目给出的条件,可以推出A->B的动态转移方程为 

dp[i][j] = max(dp[i-1][j],dp[i][j-1]) + a[i][j]; 

由于,同理可得B的情况,那么,题目的意思是A->B 然后 B -> A我们可以假设同时从A点出发,得到两条不同路

径,这个是一样的效果。所以,我们可以得到一个动态转移方程

dp[i][j][p][q] = max(dp[i-1][j][p-1][q],dp[i-1][j][p][q],dp[i][j-1][p-1][q],dp[i][j-1][p][q-1]) 

因为 每次只能移动一步,即 i+1 或j+1 那么 i+j是移动的步数 因为从A点开始移动的,经过相同的步数,肯定能得到i+j = p+q

还有一点要注意一下,这题与NYOJ 61是同类问题,但是,有一点细节要注意,最后终点的值也要算上,上面的动态方程得到的

值不包含两个A 和 B的值,因为 A是起点,所以,他的值一般是0,所以,得到最后的结果应该是 :

int sum = max(dp[m-1][n][m-1][n],dp[m-1][n][m][n-1],dp[m][n-1][m-1][n],dp[m][n-1][m][n-1]) + a[m][n]; 

一去一回可以想象成一个人从一个地方出发不过走不同的路线。


多边形面积求法:

将其分为n个三角形,并用叉乘求出所有三角形面积之和
多边形重心求法(假设质量分布均衡):
1、质量分布在每个定点上
重心坐标为(所有点横坐标和的平均, 所有点纵坐标和的平均)
2、质量完全均匀分布
先以第一个顶点为基准,分别连接p[i]、p[i+1]……(2<=i<=n),将多边形划分为若干个三角形,然
后求出所有三角形的叉积面积(可能为负!保留符号)以及重心(x1+x2+x3)/3, (y1+y2+y3)/3),
最后多边形的重心坐标就为(所有三角形重心x坐标*叉积面积的积之和/叉积面积之和,所有三角形重心y坐标*叉积面积的积之和/叉积面积之和)

1:n!的尾部的"0"全部来自因子5和因子2(一对5和2产生一个0),如果把这些因子去掉,则可符合要求(2的个数明显多于5的个数)

2:设F(n)为答案所要求的数,G(n)为1,2…n中将5的倍数的数换成1后的各项乘积,G(15)=1*2*3*4*1*6*7*8*9*
1*11*12*13*14*1(G(n)%10必不为0),则可推出以下两个公式
① n! = (n/5)! * 5^(n/5) * G(n)  ② F(n!) = F((n/5)!) * F[5^(n/5) * G(n)] (可以递归)
3:根据②可知F[5^(n/5) * G(n)] = F[G(n)/(2^(n/5))],其中G(n)/(2^(n/5))可找到规律
4:枚举可找到上述规律为Mp[20] = {1,1,2,6,4,2,2,4,2,8,4,4,8,4,6,8,8,6,8,2}(20一循环)这样就可以算出答案啦
PS:
n<=19  ----  G[n] = data[n]
n>=20  ----  G[n] = data[n%20]

n过大,这里用字符串处理


#include<stdio.h>

#include<string.h>

char str[10005];
int a[10005], Mp[20] = {1,1,2,6,4,2,2,4,2,8,4,4,8,4,6,8,8,6,8,2};  /*这个是F[5^(n/5)*G(n)]的前20(0-19)项,后面循环*/
int main(void)
{
int T, len, ret, i, c;
scanf("%d", &T);
while(T--)
{
scanf("%s", str);
len = strlen(str);
for(i=len-1;i>=0;i--)
a[len-1-i] = str[i]-'0';     /*将n的每一位存入数组a[],其中a[0]是最低位,a[len-1]是最高位*/
ret = 1;
while(len!=0)  /*用循环代替递归*/
{
c = 0;
ret = ret*Mp[a[1]%2*10+a[0]]%10;   /*"a[1]%2*10+a[0]"是计算n%20的值*/
for(i=len-1;i>=0;i--)
{
c = c*10+a[i];    /*计算n除以5之后的值,并将其存入(覆盖)a[]*/
a[i] = c/5;
c %= 5;
}
if(a[len-1]==0)     /*如果最高位是0,去掉最高位*/
len--;
}
if(strcmp(str, "1")==0 || strcmp(str, "0")==0)
printf("1\n");
else
printf("%d\n", ret);
}
return 0;
}
https://www.cnblogs.com/kuangbin/archive/2011/08/28/2156426.html
ACM博弈知识汇总



1:n!的尾部的"0"全部来自因子5和因子2(一对5和2产生一个0),如果把这些因子去掉,则可符合要求(2的个数
版权声明:求指点,让我顿悟,QAQ https://blog.csdn.net/qq_37748451/article/details/79976985

POJ 1150-The Last Non-zero Digit(求阶乘最后一位非零数)

The Last Non-zero Digit Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I...
  • u013486414
  • u013486414
  • 2015-04-05 21:04:46
  • 1181

如何计算N!的最后一位非零数字(POJ 1604 Just the Facts)

题目来源:http://acm.pku.edu.cn/JudgeOnline/problem?id=1604Sample Input122612531259999Sample Output      ...
  • Rappy
  • Rappy
  • 2007-11-26 21:31:00
  • 4536

N!(N的阶乘)最末位非0的求解方法

关于N!的最后一位非0位, 如3!=6,最后一位非0位为6, 5!=120, 最后一位非0位为2.怎么样快速的求出最后一位非0位呢?...
  • txl16211
  • txl16211
  • 2014-10-31 13:53:55
  • 1938

js找到阶乘最后面的非零位

题目:找到阶乘最后面的非零位。举个例子:5!=120所以5!的最后面的非零位是2;7!=5040,所以最后面的非零位是4。输入包括一行,为一个整数N(N<4221)。输出包括一行,为输出N!最后面的非...
  • liangyiyiliang
  • liangyiyiliang
  • 2016-06-04 13:41:34
  • 423

阶乘最后非零位

//求阶乘最后非零位,复杂度O(nlogn)//返回该位,n以字符串方式传入#include #define MAXN 10000int lastdigit(char* buf){ const int...
  • foxdot
  • foxdot
  • 2010-04-28 20:19:00
  • 913

阶乘最右边的非0位

/*描述 也许你早就知道阶乘的含义,N阶乘是由1到N相乘而产生,如: 6! = 720。因此,6的阶乘最右边的非零位为2。 写一个程序,计算N(1...
  • liangguojunainia
  • liangguojunainia
  • 2014-02-28 13:50:47
  • 1256

n的阶乘最后一个非0的数

哈哈~要说这个题目,中午比赛的时候1AC了、、归功于之前写过的求大数的阶乘这个算法啊。。 在电脑上调试了一会,发现求阶乘的过程是一段段输出的。。就比如说10的阶乘,先输出362,然后8800, 知...
  • yujuan_Mao
  • yujuan_Mao
  • 2013-04-05 16:48:42
  • 3110

阶乘数最右边一个非零数字:通用解法

给出正整数n(可能有前导0),请求出n!最右非零的数位的值。
  • zxozxo4
  • zxozxo4
  • 2015-03-17 13:50:02
  • 1386

阶乘问题(提高组)

题目:题目描述也许你早就知道阶乘的含义,N阶乘是由1到N相乘而产生,如:12! = 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x 11 x 12 = 479,001...
  • Eric1561759334
  • Eric1561759334
  • 2017-01-28 11:13:56
  • 217
收藏助手
不良信息举报
您举报文章:2018/4/17双线程dp、多边形面积求法、N阶乘最后非零位、博弈(今天本来的博客)
举报原因:
原因补充:

(最多只允许输入30个字)