hnu12263 Gluttonous robot

题目:

Gluttonous robot
Time Limit: 10000ms, Special Time Limit:25000ms, Memory Limit:65536KB
Total submit users: 11, Accepted users: 9
Problem 12263 : Special judge
Problem description
Secret laboratory of Fatown has developed a new gluttonous robot which moves on stripe consisting of n+1 cells. Cells are numbered from 0 to n. The robot is located at cell with number 0; each other cell contains several bukazoids which gluttonous robot regales oneself with. The robot can do m single jumps (to adjacent cell) and k double jumps (over one cell). Additionally, m+2k=n. All jumps are jumps forward. To feed gluttonous robot you need to write a program which finds sequence of jumps with highest number of bukazoids on a way.
Input
There are several test cases,the input will finish with the end of file. For each testcase,the first line at the input contains 3 integers: n(1 ≤ n ≤ 100), m(0 ≤ m ≤ 100), k(0 ≤ k ≤ 100). The second line contains n integers - number of bukazoids (up to 100) in corresponding cells of the stripe.
Output
The first line at the output should contain highest number of bukazoids found. The second line should contain m+k+1 integers ? numbers of cells visited by the robot, starting from cell with number 0.
Sample Input
5 1 2
5 2 7 3 1
Sample Output
13
0 1 3 5
Problem Source

2010 All-Ukrainian Collegiate Programming Contest Vinnytsia National Technical University

 

题意:就是一个机器人只能向前跳,她要么跳大临近位置,要么跳到前面隔一个位置,每个位置有事物,她从0开始跳,跳到终点,问最多能吃到多少食物

输入:n,m,k,其中n是n个格子,标号1,2,3,...n,m是跳一个的次数,k是跳两个的次数,明显有n=m+2*k,第二行输入是每个格子的事物

输出:第一行输出总的能吃多少事物,第二行是她吃做多食物时跳的步骤,从0开始

 

思路:

刚开始看1<=n<=100,0<=m<=100,0<=k<=100,想直接搜索,tle了,后来想了个剪枝,就是从反面考虑,如果她到某格没吃多的已经多与她一次吃食物最多时没吃过的,就排除,结果。。。。没什么效果。

看别人做都是0ms,15ms,后来睡觉醒的时候想到了是dp,dp不太会,不好描述,就是开一个数组,f[a][b],a,b分别是跳一次和跳两次的次数,则有

:f[a][b]=max(f[a-1][b]+temp[a+2*b],f[a][b-1]+temp[a+2*b]),其中temp数组记录每个格子的食物,然后开始写了。又开始wa,原来没考虑到为0的时候特别一点。继续wa,又发现我是用一个一维len数组记录最大值时候的格子,然后回溯,但是有可能后面相同长度但不是最大时改变,

开始时:len[a+2*b]=a-1+2*b,这是举个例子,比如取a-1,b,后面会出现相同长度的,改变了原数组,于是写了个结构体,path[x][y].x=a-1,path[x][y].y=b,好像可以了吧

。。又表露出我的练习少,后面回溯时不小心把变量改变了,又错了,改过来后,终于ac,了,不容易呀!!!慢慢努力吧!

代码:

#include<iostream>

using namespace std;
int n,m,k;
int temp[300];
int f[105][300];
struct point{
int x;
int y;
}path[300][300];
int len[300];
int main()
{
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
for(int i=1;i<=n;i++)
scanf("%d",&temp[i]);
memset(f,0,sizeof(f));
memset(path,0,sizeof(path));
memset(len,0,sizeof(len));
f[1][0]=temp[1];
f[0][1]=temp[2];
path[1][0].x=path[1][0].y=path[0][1].x=path[0][1].y=0;
for(int i=0;i<=m;i++)
for(int j=0;j<=k;j++)
if(i==0&&j==0)//不可能同时为0
continue;
else if(j==0)//如果一方为0,就可以直接判断了
{
f[i][j]=f[i-1][j]+temp[i+2*j];
path[i][j].x=i-1;
path[i][j].y=j;

}
else if(i==0)
{
f[i][j]=f[i][j-1]+temp[i+2*j];
path[i][j].x=i;
path[i][j].y=j-1;
}
else if(f[i-1][j]+temp[i+2*j]>f[i][j-1]+temp[i+2*j])//dp,关键
{
f[i][j]=f[i-1][j]+temp[i+2*j];
path[i][j].x=i-1;
path[i][j].y=j;
}
else
{
f[i][j]=f[i][j-1]+temp[i+2*j];
path[i][j].x=i;
path[i][j].y=j-1;
}
printf("%d\n",f[m][k]);
int count1=2;
int a, b;
for(int i=path[m][k].x, j=path[m][k].y;!(i==0&&j==0);i=path[a][b].x,j=path[a][b].y)//开始时没用a,b结果j代换之前,i已代换,所以错了
{
len[count1++]=i+2*j;
a=i;b=j;
}
len[1]=n;
printf("%d",len[0]);
for(int i=count1-1;i>=2;i--)//输出有点繁琐
printf(" %d",len[i]);
printf(" %d\n",len[1]);
}
//system("pause");
return 0;
}

 

总结:

1.考虑要周全,dp要多思考,练习做过的题目

2.多敲代码,减少错误

3.要冷静,不气馁

 

****************************************************************************

我相信我一定会冉冉升起的

 

posted @ 2012-03-11 13:12  xingyezhi  阅读(333)  评论(0编辑  收藏  举报