今天突然心血来潮想写一篇博客,一切的想法来源于这一道题,
求(n,n)点的最少减速速度,可以转化为求(n-1,n)和(n,n-1)两点的最少减速速度,然后加上(n,n)点的减速速度,转化为最优子问题,
用动态规划,这里采用自下而上的解法。
#include<stdio.h>
int main()
{
long long int i,j,n;
scanf("%lld",&n);
long long int a[n][n];
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
scanf("%lld,",&a[i][j]);
}
long long int min[n][n];
for(i=n-1;i>=0;i--)
for(j=n-1;j>=0;j--)
{
if(i==n-1&&j==n-1) min[i][j]=a[i][j];
else if(i==n-1) min[i][j]=a[i][j]+min[i][j+1];
else if(j==n-1) min[i][j]=a[i][j]+min[i+1][j];
else min[i][j]=a[i][j]+(min[i][j+1]<=min[i+1][j]?min[i][j+1]:min[i+1][j]);
}
printf("%lld",min[0][0]);
return 0;
}
- 下面这种方法是自上而下,不过要进行打表处理,可能耗时比较长,推荐还是用上面的那种
#include <iostream> #include <algorithm> #include <cstdio> using namespace std; int a[10010][10010]; int main() { int n; cin>>n; for(int i=0;i<=n;i++) { a[0][i] = a[i][0] = 1<<30; } a[1][0] = a[0][1] = 0; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { cin>>a[i][j]; getchar(); a[i][j]+=min(a[i-1][j], a[i][j-1]); } } cout<<a[n][n]<<endl; return 0; }
算法的主要思想理解了,下面这两道入门级别的题目,大家可以试试水,看看有没有效率更高的解法,欢迎大家在下方讨论
-
救雅典娜
时间限制:C/C++语言 1000MS;其他语言 3000MS
内存限制:C/C++语言 65536KB;其他语言 589824KB
题目描述:
黄金圣斗士欧洛斯要去圣域救雅典娜,需要从左上角出发,每次只能向右或向下走,最后达到右下角见到雅典娜。地图每个位置的值代表圣斗士要遭遇的事情,如果是负数,说明此处有阻击,要让圣斗士损失血量,如果是非负数,代表此处有血瓶,能让圣斗士回血,圣斗士从左上角走到右下角的过程中,走到任何一个位置时,血量都不能少于1,为了保证圣斗士能救出雅典娜,初始血量至少是多少?地图为一个二维数组map,如下矩阵。根据map,返回初始血量。
输入
一个n*m的二维数组第一行:数组的行数n(n>0)
第二行:数组的列数m(m>0)
第三行:数组,每个位置的血量,行优先
输出
对于每个测试实例,要求输出初始血量样例输入
3
3
-2 -3 3 -5 10 1 0 30 -5
样例输出
6 -
英雄PK
时间限制:C/C++语言 1000MS;其他语言 3000MS
内存限制:C/C++语言 65536KB;其他语言 589824KB
题目描述:
AB两队进行PK,每队有n个英雄,每局一个英雄出战进行PK,(且每个英雄只能出战一次),每个英雄都有武力值,武力值大的英雄获胜,武力值相同平局,平局没有得失,每赢一局该队获得100个元宝,输一局损失100个元宝。求A队最多可以赢多少元宝。输入
第一行:一个正整数n(0