300分冰天雪地裸身跪求一个算法题解答,急,在线等~~~~~~~

cctvufo 2008-03-15 02:21:32
frog问题

描述:
一只小青蛙在一个一维路径上抓虫子吃,一共有N格,每次能跳T步(a<=T<=b),跳了K次后就会痿掉,跳不动了,游戏结束。每跳到一个格子上就能把那个格子上的虫子吃完,一开始青蛙在第一格上(上面的虫子(如果有的话)就自然被吃掉了)



输入:
第一行需要用户输入N, A, B(1 <= A <= B <= N), K (K >= 1).
第二行需要用户输入每一格的虫子数量



输出:
程序输出这种状态下能吃的虫子最大数目


样例输入:
4 1 2 2
1 2 3 4


样例输出:
8


3:30前给出答案一定给到300分
绝不食言
现在只有100
人气旺加到200

急~~~~~~~~~~~~~~~~~~~~~~~~~·
...全文
1192 90 打赏 收藏 转发到动态 举报
写回复
用AI写文章
90 条回复
切换为时间正序
请发表友善的回复…
发表回复
hastings 2008-03-21
  • 打赏
  • 举报
回复
帖子的题目真是狠
butwang 2008-03-21
  • 打赏
  • 举报
回复
似乎都得了0分
chuengchuenghq 2008-03-21
  • 打赏
  • 举报
回复
帮你顶
ochinchina 2008-03-21
  • 打赏
  • 举报
回复
动态规划:

#include <stdio.h>

int frog( int N, int a, int b, int start, int k, int *insects, int** result )
{
int max = 0, tmp = 0;
int i;

if( start >= N || k < 0 ) {
return 0;
}

if( result[start][k] >= 0 ) {
return result[start][k];
}

for( i = a; i <= b; i ++ ) {
if( k > 0 ) {
tmp = frog( N, a, b, start + i, k - 1, insects, result );
if( tmp > max ) {
max = tmp;
}
}

}

max += insects[start];
if( result[start][k] < max ) {
result[start][k] = max;
}
return result[start][k];
}

int** allocMatrix( int row, int column )
{
int i, j;
int ** r = (int**)malloc( row * sizeof( int* ) );

for( i = 0; i < row; i++ ) {
r[i] = (int*) malloc( column * sizeof( int* ) );

for( j = 0; j < column; j++ ) {
r[i][j] = -1;
}
}

return r;
}

int main( int args, char** argv )
{
int N = 140;
int k = 100;
int a = 2;
int b = 5;
int insects[140];
int i = 0;

int **result = allocMatrix( N, k + 1 );

for( i = 0; i < N; i++ ) {
insects[i] = i + 1;
}

int r = frog( N, a, b, 0, k, insects, result );

printf( "result=%d\n", result[0][k] );


}
linglongyouzhi 2008-03-21
  • 打赏
  • 举报
回复
show pp
dead_of_winter 2008-03-20
  • 打赏
  • 举报
回复
ACM题 看起来是动态规划
blueshame 2008-03-20
  • 打赏
  • 举报
回复
个人觉得,既然可以跳K步就挂了,那么是不是可以将N个格子从大到小选K个,然后按选出来的虫子去吃,如果不可达,就换下一个组合,对于是不是可以的组合也很容易判断,因为第一步跳出去了,其实就已经有了一个范围,那么然后再将K个数去小取大,再跳第二次,也是同样的道理
blueshame 2008-03-20
  • 打赏
  • 举报
回复
我觉得大家没必要贴出程序,只要一个伪代码就行了,主要说思路
写代码难,看别人的代码就更难,看程序也看不出什么门路
huang_yu_qiang 2008-03-20
  • 打赏
  • 举报
回复
理论上只有穷举所有方案,然后比较最大值,才能得出正确答案,显然这么做计算量太大。
要不就首先对这条一维路径进行经验分析,划分为几大类型,对不同类型采取不同算法。
huang_yu_qiang 2008-03-20
  • 打赏
  • 举报
回复
说明一下:
我没有研究过贪婪算法,只是给出了一个自己的想法。
这个算法“每次跳跃到虫子最多的那格里去”。也就是说缺乏“战略眼光”。当虫子聚集在远端某个区域时,这只虫子不会聪明的尽快赶去哪里
:)
huang_yu_qiang 2008-03-20
  • 打赏
  • 举报
回复

// FrogGame.cpp : Defines the entry point for the console application.
//
/*
* frog问题
描述:
一只小青蛙在一个一维路径上抓虫子吃,一共有N格,每次能跳T步(a <=T <=b),
跳了K次后就会痿掉,跳不动了,游戏结束。每跳到一个格子上就能把那个格子上的虫子吃完,
一开始青蛙在第一格上(上面的虫子(如果有的话)就自然被吃掉了)

输入:
第一行需要用户输入N, A, B(1 <= A <= B <= N), K (K > = 1).
第二行需要用户输入每一格的虫子数量

输出:
程序输出这种状态下能吃的虫子最大数目

*/
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers

#include <iostream>
#include <memory>
#include <assert.h>

using namespace std;

class Path
{
public:
Path(const int n, const int* c)
: N_(n)
{
C_ = new int[N_];
memcpy(C_, c, N_*sizeof(int));
}
virtual ~Path()
{
delete[] C_;
}
int at(const int idx)
{
assert(idx < N_);
return C_[idx];
}
int findMax(const int from, const int to)
{
assert(from >= 0);
assert(from <= to);
assert(to < N_);
int result = from;
for (int i=from+1; i<=to; ++i)
{
if (C_[result] < C_[i])
result = i;
}
return result;
}
int length()
{
return N_;
}
void clean(const int idx)
{
assert(idx < N_);
C_[idx] = 0;
}
void print()
{
for (int i=0; i<N_; ++i)
{
cout << C_[i] << " ";
}
cout << endl;
}
private:
const int N_; // 一维路径的格数
int* C_; // 每一格的虫子数量
};

class Frog
{
public:
Frog(const int k, const int a, const int b)
: K_(k), A_(a), B_(b)
{
}
virtual ~Frog()
{
}
int go(Path& path)
{
int nEated = path.at(0);
path.clean(0);
path.print();
int idx;
if (B_ > path.length() - 1)
{
idx = path.findMax(A_, path.length() - 1);
}
else
{
idx = path.findMax(A_, B_);
}
nEated += path.at(idx);
path.clean(idx);
path.print();
int k = 1;
while (k < K_)
{
int ll = idx - B_;
int lr = idx - A_;
int rl = idx + A_;
int rr = idx + B_;
if (ll < 0)
{
ll = 0;
if (lr < 0)
{
lr = 0;
}
}
if (rr > path.length()-1)
{
rr = path.length()-1;
if (rl > path.length()-1)
{
rl = path.length()-1;
}
}
int left = path.findMax(ll, lr);
int right = path.findMax(rl, rr);
if (path.at(left) > path.at(right))
idx = left;
else
idx = right;
nEated += path.at(idx);
path.clean(idx);
path.print();
k++;
}
return nEated;
}
private:
const int K_; // 跳了K次后就会痿掉
const int A_; // 每次能跳T步(a <=T <=b)
const int B_; // 每次能跳T步(a <=T <=b)
};


int main(int argc, char* argv[])
{
while (1)
{
cout << "Frog游戏" << endl;
cout << "输入" << endl;
cout << "第一行需要用户输入N(N <= 100), A, B(1<=A<=B<=N), K(K > = 1)" << endl;
int N, A, B, K;
cin >> N >> A >> B >> K;
if (A < 1 || A > B || B > N || K < 1 || N > 100)
{
cerr << "输入错误" << endl;
return 1;
}
cout << "第二行需要用户输入每一格的虫子数量" << endl;
int* C = new int[N];
for (int i = 0; i < N; ++i)
cin >> C[i];

cout << "输出" << endl;
Path path(N, C);
Frog frog(K, A, B);
cout << frog.go(path) << endl;
}
return 0;
}

sharon19860830 2008-03-17
  • 打赏
  • 举报
回复
關注關注~~~
tianjiao85 2008-03-17
  • 打赏
  • 举报
回复
MARK
haierjodn 2008-03-17
  • 打赏
  • 举报
回复
baihacker方法很容易理解,不过负责多太大,健壮性不够
星羽 2008-03-17
  • 打赏
  • 举报
回复
好长的贴 - -
态度决定品质 2008-03-17
  • 打赏
  • 举报
回复
有一点儿不太明白,T的取值是每跳一次取一个值还是每一个结果取一根值?
两种情况下结果不同。
Mnky 2008-03-17
  • 打赏
  • 举报
回复
主要优化思想就是简化下一步位置的判断,所有可能位置存入step数组。
不过楼主的1314ms的测试例是哪个呢?不是 1 4 2 2 吧?要不机器也太慢了。。。
我上面的程序测 10 1 5 9(1-10)只要15ms。
不过,如果要考虑重复跳跃问题,就会慢好多好多。。。
Mnky 2008-03-17
  • 打赏
  • 举报
回复
把Baihacker的程序优化了一下,快了好多!!!
我测了几次是OK的,不知道有没有别的错误,大家测试测试吧。

#include <iostream>
using namespace std;

int curr_max;
int *data;
int len;
int min_step;
int max_step;
int *step;
int n_steps;

void TraceBack(int left_steps,int place,int curr)
{
int t = data[place];
curr += t;
data[place] = 0;
if (left_steps)
{
for(int i=0;place + step[i] < 0;++i)
;
for (; i < n_steps && place + step[i] < len; ++i)
{
if(data[place + step[i]]>0) // 如过要考虑重复跳,就把这行注释掉
TraceBack(left_steps-1,place + step[i],curr);
}
}
else
{
if (curr > curr_max) curr_max = curr;
}
data[place] = t;
}

int main()
{
int k;
cin >> len >> min_step >> max_step >> k;

n_steps=(max_step-min_step+1)*2;
data = new int [len];
step = new int [n_steps];

for (int i = 0; i < len; ++i)
cin >> data[i];

for(i=min_step;i<=max_step;i++)
{
step[n_steps/2+(i-min_step)]=i;
step[n_steps/2-(i-min_step)-1]=-i;
}
curr_max = -1;

TraceBack(k,0,0);
cout << curr_max << endl;
return 0;
}


不过输入有个限制,就是k<=n,因为如果所有点提前访问完了,则结果是-1,而不是提前结束。
此外,需要a<=b,所有点都有虫子(否则会误以为该点访问过)。
red_berries 2008-03-16
  • 打赏
  • 举报
回复
吃青蛙啦
ttlyfast 2008-03-16
  • 打赏
  • 举报
回复
接 分
加载更多回复(70)

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧