1、8*8的棋盘上面放着64个不同价值的礼物,每个小的棋盘上面放置一个礼物(礼物的价值大于0),一个人初始位置在棋盘的左上角,每次他只能向下或向右移动一步,并拿走对应棋盘上的礼物,结束位置在棋盘的右下角,请设计一个算法使其能够获得最大价值的礼物。
//经典的动态规划
//dp[i][j] 表示到棋盘位置(i,j)上可以得到的最大礼物值
//dp[i][j] = max( dp[i][j-1] , dp[i-1][j] ) + value[i][j] (0<i,j<n)
int i, j, n = 8;
dp[0][0] = value[0][0];
for( i = 1 ; i < n ; i++ )
{
dp[i][0] = dp[i-1][0] + value[i][0];
}
for( j = 1 ; j < n ; j++ )
{
dp[0][j] = dp[0][j-1] + value[0][j];
}
for( i = 1 ; i < n ; i++ )
{
for( j = 1 ; j < n ; j++ )
{
dp[i][j] = max( dp[i][j-1] , dp[i-1][j] ) + value[i][j];
}
}
cout<<dp[n-1][n-1]<<endl;
扩展:现在增加一个限定值limit,从棋盘的左上角移动到右下角的时候的,每次他只能向下或向右移动一步,并拿走对应棋盘上的礼物,但是拿到的所有的礼物的价值之和不大于limit,请设计一个算法请实现。
int row,col;
int limit;
int dp[row][col][limit];
int getMaxLessLimit()
{
memset(dp,0,sizeof(dp));
for(int r = row-1 ; r >= 0; r--)
{
for(int c = col-1 ; c >= 0; c--)
{
for(int l = 0 ; l <= limit; l++)
{
if(l >= matrix[r][c])
{
int max = 0;
if(r != row-1 && dp[r+1][c][l-matrix[r][c]]>max)
max = dp[r+1][c][l-matrix[r][c]];
if(c != col-1 && dp[r][c+1][l-matrix[r][c]]>max)
max = dp[r][c+1][l-matrix[r][c]];
if(max == 0 && !(r == row-1 && c == col-1))
dp[r][c][l] = 0;
else
dp[r][c][l] = max + matrix[r][c];
}
}
}
}
return dp[0][0][limit];
}
或者
int hash[row][col][limit];
int getMaxLessLimit()
{
memset(hash,0,sizeof(hash));
hash[0][0][matrix[0][0]] = 1;
for(int i = 0 ; i < row ; i++)
{
for(int j = 0 ; j < col ; j++)
{
for(int k = 0 ; k <= limit ; k++)
{
if(k >= matrix[i][j])
{
if(i >= 1 && hash[i-1][j][k-matrix[i][j]])
hash[i][j][k] = 1;
if(j >= 1 && hash[i][j-1][k-matrix[i][j]])
hash[i][j][k] = 1;
}
}
}
}
int ans = 0;
for(int k = limit; k >= 0; k--)
{
if(hash[row-1][col-1][k] && k>ans)
ans = k;
}
return ans;
}
2、有两个字符串s1和s2,其长度分别为l1和l2,将字符串s1插入到字符串s2中,可以插入到字符串s2的第一个字符的前面或者最后一个字符的后面,对于任意两个字符串s1和s2,判断s1插入到s2中后是否能够构成回文串。。
3、已知有m个顶点,相邻的两个顶点之间有一条边相连接,首尾顶点也有一条边连接,这样就构成了一个圆环。
现在有一个二维数组M[][]