输入包括一行,逗号隔开的两个正整数x和y,取值范围[1,10]。
输出包括一行,为走法的数目。
3 2
10
网格点我是服气的
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int x = scanner.nextInt();
int y = scanner.nextInt();
System.out.println(dp(x, y));
}
public static int dp(int x,int y) {
//从起点到i,j的走法总数
int [][]dp = new int[x + 1][y + 1];
for (int i = 1;i <= y;i ++) {
dp[0][i] = 1;
}
for (int i = 1;i <= x;i ++) {
dp[i][0] = 1;
}
for (int i = 1;i <= x;i ++) {
for (int j = 1;j <= y;j ++) {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
return dp[x][y];
}
}
import java.util.Scanner;
public class Main {
//网格走法数目
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int m,n;
m = in.nextInt();
n = in.nextInt();
int f[][] = new int[11][11];
f[0][0] = 0;
for(int i=0; i<=m; i++)
f[i][0] = 1;
for(int i=0; i<=n; i++)
f[0][i] = 1;
for(int i=1; i<=m; i++){
for(int j=1; j<=n; j++)
f[i][j] = f[i-1][j] + f[i][j-1];
}
System.out.print(f[m][n]);
}
} 非常经典的动态规划 做过很多变种 这个是最简单的类型
要注意题目的意思 x y是格点 所以都要加一
#include<iostream>
using namespace std;
int dp[15][15];
int main(){
int x, y;
scanf("%d%d", &x, &y);
for(int i = 1; i <= x + 1; i++) dp[i][1] = 1;
for(int i = 1; i <= y + 1; i++) dp[1][i] = 1;
for(int i = 2; i <= x + 1; i++)
for(int j = 2; j <= y + 1; j++)
dp[i][j] = dp[i-1][j] + dp[i][j-1];
printf("%d\n", dp[x+1][y+1]);
}
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
int y = sc.nextInt();
int[][] fcount = new int[x+1][y+1];
for(int i = 0 ; i <= x;i++) {
fcount[i][0] = 1;
}
for(int i = 0; i <= y;i++) {
fcount[0][i] = 1;
}
for(int i = 1;i <= x;i++) {
for(int j = 1;j <= y;j++) {
fcount[i][j] = fcount[i-1][j] + fcount[i][j-1];
}
}
System.out.println(fcount[x][y]);
}
} import java.util.Scanner;
public class Main{ // 直接C(n+m,n)
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long n = sc.nextInt();
long m = sc.nextInt();
System.out.println(recursive_C(n + m, m));
}
// C(n,m)
public static long recursive_C(long n, long m) {
return getNFactorial(n) / getNFactorial(m) / getNFactorial(n - m);
}
// n!
public static long getNFactorial(long n) {
if (n == 0) {
return 1;
}
return n * getNFactorial(n - 1);
}
} #include <iostream>
using namespace std;
long long int factorial(int m);
int main(int argc, const char * argv[])
{
int x,y;
cin>>x>>y;
long long int ways;
ways=factorial(x+y)/(factorial(x)*factorial(y));
cout<<ways;
}
long long int factorial(int m)
{
long long int total=1;
int i=1;
for(;i<=m;i++)
{
total=total*i;
}
return total;
}
while(line = readline()){
var lines = line.split(' ');
var a = parseInt(lines[0]),
b = parseInt(lines[1]);
function cellCount(x,y){
var arr =[];
//每个格点初始化为1
for(var i=0; i<=x;i++){
arr[i]=[];
for(var j=0; j<=y;j++){
arr[i][j] = 1;
}
}
//每个格点的值是其左边和上边格点值的和
for(var i=1;i<=x;i++){
for(var j=1;j<=y;j++){
arr[i][j] = arr[i-1][j] + arr[i][j-1];
}
}
return arr[x][y];
}
print(cellCount(a,b));
} 两个思路,一种动态规划,一种是递归,其实原理都是一样的。 都是通过状态转移方程找到边界条件来求解。
可以看出网格中的到达网格中的任意一点的状态方程为: d(m,n)=d(m-1,n)+d(m,n-1)
也就是到达相邻的左节点和上节点的所有路线的和
边界条件:到达所有处于第一行跟第一列的所有的点的路线都只有一条。
知道了状态方程跟 边界条件,那么我们就可以使用动态规划来解决了;
这里附上两个解法,第一个是动态规划,第二个是递归
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int m = sc.nextInt();
int n = sc.nextInt();
//动态规划
System.out.println(dpHandle(init(m, n),m, n));
//递归
//System.out.println(recursiveHandle(init(m, n), m, n));
}
}
public static int dpHandle( int[][] a ,int m, int n) {
for (int i = 1; i < a.length; i++) {
for (int j = 1; j < a[i].length; j++) {
a[i][j] = a[i - 1][j] + a[i][j - 1];
}
}
return a[m][n];
}
public static int[][] init(int m, int n) {
int[][] a = new int[m + 1][n + 1];
for (int i = 0; i < a[0].length; i++) {
a[0][i] = 1;
}
for (int i = 0; i < a.length; i++) {
a[i][0] = 1;
}
return a;
}
public static int recursiveHandle(int[][] a, int m, int n) {
if (m == 0 && n == 0) {
return 0;
}
if (m == 0 || n == 0) {
return 1;
}
return recursiveHandle(a, m - 1, n) + recursiveHandle(a, m, n - 1);
}
}
解题思路:Nx1的网格 以及 1xN的网格都遵循 起点到终点的方法数为:N+1,其他点等于“肩上”两个网格的和,所有算法采用递归实现
import sys
net = sys.stdin.readline().split()
x = int(net[0])
y = int(net[1])
def rec(x,y):
if(x==1)or(y==1):
return x+y
else:
return rec(x-1,y)+rec(x,y-1)
print(rec(x,y))
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] s = br.readLine().split(" ");
int x = Integer.parseInt(s[0]);
int y = Integer.parseInt(s[1]);
int[] dp=new int[y+1];
Arrays.fill(dp,1);
for(int i=1;i<=x;i++)
for(int j=1;j<=y;j++)
dp[j]+=dp[j-1];
System.out.print(dp[y]);
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int m = scan.nextInt(), n = scan.nextInt();
//排列组合 m+n步选取m步
long a = 1, b = 1, c = 1;
for (int i = 1; i <= m+n; i++) a *= i;
for (int i = 1; i <= m; i++) b *= i;
for (int i = 1; i <= n; i++) c *= i;
System.out.println(a/(b*c));
}
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
int y = sc.nextInt();
// 初始化边界
int[][] dp = new int[x + 1][y + 1];
for(int i = 0; i <= x; i++)
dp[i][0] = 1;
for(int i = 0; i <= y; i++)
dp[0][i] = 1;
// 动态规划
for(int i = 1; i <= x; i++){
for(int j = 1; j <= y; j++)
dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; // 可能从上面,也可能从左边过来
}
System.out.println(dp[x][y]);
}
} #include <iostream>
using namespace std;
int main()
{
int nRows, nCols;
while (cin >> nRows >> nCols)
{
if (nRows < 1 || nRows > 10 || nCols < 1 || nCols > 10)
{
cout << "0" << endl;
continue;
}
int* pDP = new int[nRows + 1];
for (int i = 0; i <= nCols; ++i)
pDP[i] = 1;
for (int i = 1; i <= nRows; ++i)
for (int j = 1; j <= nCols; ++j)
pDP[j] = pDP[j - 1] + pDP[j];
cout << pDP[nCols] << endl;
delete pDP;
}
} 递归即可解决该问题,好好的学习递归真的很有用,哈哈,共勉import java.util.Scanner; public class root { public static void main(String[] args){ Scanner input = new Scanner(System.in); while (input.hasNextInt()){ int disX = input.nextInt(); int disY = input.nextInt(); System.out.println(road(0,0, disX,disY)); } } public static int road(int x, int y, int disX, int disY){ int result = 0; if (x <= disX && y <= disY){ if (x == disX && y == disY){ return 1; }else { //向下走 result = result + road(x + 1, y, disX, disY); //向右走 result = result + road(x , y + 1, disX, disY); } return result; }else { return 0; } } }