UVALive 3720 Highways
2016-07-25 17:40
197 查看
UVALive 3720 Highways
链接:UVALive 3720题意:给出一个mxn的矩形点阵,问除了水平和竖直的线,最多可以添加多少条不重复且不覆盖的连线?
思路:组合数学,但是可以打表找出前几项的规律,然后dp。先遍历每个点为之前矩阵所增加的连线,然后再遍历一遍,将这些点的贡献求和再减去重复的。只求左上到右下的,根据对称性,最后结果乘以二。
dp1[i][j]=dp1[i-1][j]+dp1[i][j-1]-dp1[i-1][j-1]+(gcd(i,j)==1);//i,j互质则说明有一条新的斜率的线
dp2[i][j]=dp2[i-1][j]+dp2[i][j-1]-dp2[i-1][j-1]+dp1[i][j]-dp1[i/2][j/2];
下面是完整代码:
#include <cstdio> #include <iostream> #include <cstring> #include <cstdlib> #include <cmath> #include <set> #include <algorithm> #include <map> #include <bitset> #include <vector> #include <queue> #include <stack> #include <utility> #include <functional> #include <sstream> #include <list> #include <complex> #include <ctime> using namespace std; #define ll long long #define ull unsigned long long const int MAXN=100005; const int INF=987654323; const int MOD=1e9+7; ll dp1[305][305],dp2[305][305]; ll m,n; ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); for(int i=1;i<=300;i++) for(int j=1;j<=300;j++) dp1[i][j]=dp1[i-1][j]+dp1[i][j-1]-dp1[i-1][j-1]+(gcd(i,j)==1); for(int i=1;i<=300;i++) for(int j=1;j<=300;j++) dp2[i][j]=dp2[i-1][j]+dp2[i][j-1]-dp2[i-1][j-1]+dp1[i][j]-dp1[i/2][j/2]; cin>>n>>m; while(n||m){ cout<<(dp2[n-1][m-1]<<1)<<endl; cin>>n>>m; } return 0; }
相关文章推荐
- 用批处理解决数学问题的代码第1/4页
- Oracle数学相关函数小结
- php常用数学函数汇总
- 详解Android应用中屏幕尺寸的获取及dp和px值的转换
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- 无限循环小数
- LFC1.0.0 版本发布
- 数学书籍备忘
- Android dpi,dip,dp的概念以及屏幕适配
- Oracle数学相关函数小结
- 建立以人为本的数学课程观
- 文兴小学2008-2009学年度第一学期数学科教学计划
- 玩转Bash脚本:数值计算
- MySql函数大全<二>
- 一生受用的数学公式
- oracle中行列转换
- 数学猜想
- 世界第一数学强校的背后
- 数学是一种思考方式