cogs 49. 跳马问题 DFS dp

49. 跳马问题

★   输入文件:horse.in   输出文件:horse.out   简单对比
时间限制:1 s   内存限制:128 MB

【问题描述】

    有一只中国象棋中的 “ 马 ” ,在半张棋盘的左上角出发,向右下角跳去。规定只许向右跳(可上,可下, 但不允许向左跳)。请编程求从起点 A(1,1) 到终点 B(m,n) 共有多少种不同跳法。

 
 【输入格式】
 
    输入文件只有一行,两个整数m和n(1≤m,n≤20),两个数之间有一个空格。
 【输出格式】
 
    输出文件只有一个整数,即从 A 到 B 全部的走法。
 
 【输入输出样例】
 
   输入文件(horse.in)
   5 9
 
  输出文件(horse.out)
   37   自动选择评测机   gcc/g++4.8.5gcc/g++4.8.5 -O2gcc/g++4.8.5(C++11)gcc/g++4.6.3gcc/g++4.6.3 -O2         
提交代码 Pascal C C++
天哪 这可真是一道水水水水题啊
 
我就不用DFS来做了
用一下动态规划试试看!
其实看起来还是比较简单的
f[i][j] = f[i - 2][j - 1] + f[i - 2][j + 1] + f[i - 1][j - 2] + f[i - 1][j + 2];
然后i和j都从小往大枚举for循环
其实也就是从左往右 从上往下
至于正确性?不好证明。。
但是确实卡过了诶 QaQ 
左右上方四个点的和
 
说实话 这一道题 调起来确实挺费劲的
#include<bits/stdc++.h>
using namespace std;
int f[1005][1005];
int main()
{
    freopen("horse.in","r",stdin);
    freopen("horse.out","w",stdout);
    int n,m;
    scanf("%d%d",&n,&m);
    f[1][1]=1;
    for(int i=2;i<=m;i++)
        for(int j=1;j<=n;j++)
            f[i][j]=f[i-2][j-1]+f[i-2][j+1]+f[i-1][j-2]+f[i-1][j+2];
    printf("%d",f[m][n]);
    
    return 0;
}

 

 
 
 

转载于:https://www.cnblogs.com/Tidoblogs/p/11469885.html

以下是将代码修改为cot平滑的方法: 1. 首先,需要使用边界角的cot权重计算每个顶点的权重。 2. 然后,使用cot权重对每个顶点的邻域点进行加权计算,得到平滑后的坐标。 3. 最后,根据平滑后的坐标更新每个顶点的位置。 修改后的代码如下: float smooth() { float err = -1; cogs.clear(); v_end = mesh.vertices_end(); //cot平滑 for (v_it = mesh.vertices_begin(); v_it != v_end; ++v_it) { cog[0] = cog[1] = cog[2] = weight_sum = 0.0; for (vv_it = mesh.vv_iter(*v_it); vv_it.is_valid(); ++vv_it) { double cot_weight = 0.0; MyMesh::HalfedgeHandle heh = mesh.find_halfedge(*v_it, *vv_it); if (!mesh.is_boundary(heh)) { MyMesh::HalfedgeHandle prev_heh = mesh.prev_halfedge_handle(heh); MyMesh::HalfedgeHandle next_heh = mesh.next_halfedge_handle(heh); MyMesh::VertexHandle prev_vh = mesh.to_vertex_handle(prev_heh); MyMesh::VertexHandle next_vh = mesh.to_vertex_handle(next_heh); MyMesh::Point prev_p = mesh.point(prev_vh); MyMesh::Point curr_p = mesh.point(*v_it); MyMesh::Point next_p = mesh.point(next_vh); double cot_alpha = cot(prev_p - curr_p, next_p - curr_p); double cot_beta = cot(curr_p - prev_p, next_p - prev_p); cot_weight = cot_alpha + cot_beta; } cog += cot_weight * mesh.point(*vv_it); weight_sum += cot_weight; } cogs.push_back(cog / weight_sum); } for (v_it = mesh.vertices_begin(), cog_it = cogs.begin(); v_it != v_end; ++v_it, ++cog_it) { if (!mesh.is_boundary(*v_it)) { MyMesh::Point p = mesh.point(*v_it); err = max(err, (p - *cog_it).norm()); mesh.set_point(*v_it, *cog_it); } } return err; } 其中cot函数的定义如下: double cot(MyMesh::Point a, MyMesh::Point b) { return dot(a, b) / cross(a, b).norm(); } 注意,这里使用的是边界角的cot权重,因此在计算cot权重时需要判断当前边是否为边界。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值