/*
计划聚会:问题描述:就是对于一个公司而言的话形成的管理体系是如下的情况:以总裁为根的一棵树,之后往下进行扩展,分左子树以及右子树,现在要求的是
每一层的每一个节点都有一个对聚会的喜欢程度,但是限制条件是雇员和他的直接上司是不可以同时参加的,现在就是求这个的期望总和是最大的情况;
解法:我们对于某一层的一个节点进行讨论,如果该节点参加的话,把这个节点涂色为红色,不参加的话涂色为白色,对应的可以得到的是一个涂色的树,那么的话
对于这个树的期望程度可以表示为T(x,c)其中x表示为节点,c对应的为它的颜色,那么的话,对应的节点的期望程度是v(书上说这是一个常量),相应的可以计算出节点
的期望程度公式是:1,如果是叶子节点,即x下面没有其他的节点:T(x,c)=v(如果红色,即不参加)或者0(如果白色,即参加),这就是一个最优子结构;2.当是非叶子节点
那么可以使用如下的式子进行计算T(x,c)=v+T(x子树们,白色):这个是当是x为红色的时候,(那么由于x参加,对应的子树必定不会参加喽)就是下面的子树使用白色操作
,2.T(x,c)=max(T(子树们,白色),T(子树们,红色)),由于是当x的颜色是白色即这个节点不参加,对应的孩子可能会参加,可能不会参加,那么的话这就是子结构了;
*/
//代码的话,简化的话对于节点的出现次序假设自己是知道的,如果是要程序自动判断的话,我们就需要涉及到二叉树,尼玛如果不是二叉树,更复杂了···这里不写
/*
棋盘上移动:问题描述:nXn的棋盘,存在着如下的关系,就是从盘底的某一个行开始,到盘顶的某一个位置位置,这就是棋盘的移动过程,棋子的移动过程要遵守的
规则是这样的,从某一个位置往上移动的话存在的三种可能性:1.直接移到(x,y)的上一个(x,y+1);2.移到(x+1,y)左上(当然是不能够有最左的情况)(x+1,y-1);3.对称的
(x+1,y-1);对于这三种情况进行分析,此外题目还说从从点x到y的距离的消费是p(x,y),那么我们如果需要达到上面的要求的话,需要让开销最大,则是怎么算的?
解法:假设开销c[i][j],为到达点(i,j)开销。我们知道的是假设到达点(i,j)之前的话需要涉及到的点的可能性有三种,我们从这三种情况进行分析得到最后的结果:1.如果是从节点(i-1,j)往上直走到达(i,j)
2;从(i-1,j-1)往右上走到达;3.从(i-1,j+1)往左上直走到达。
对应的开销计算如下1:c[i][j]=c[i-1][j]+p[(i-1,j)][(i,j)](j>1);2.c[i][j]=c[i-1][j-1]+p[(i-1,j-1)][(i,j)];3.c[i][j]=c[i-1][j+1]+p[(i-1,j+1)][(i,j)];
(j<n)
*/
#include<iostream>
using namespace std;
#define N 10
struct money
{
int n;//实际的矩形边长
int c[N][N];
int p[N][N][N][N];//这个是木有办法啊,只能先这样了;
int w[N][N];
money(int num):n(num){
for (int i=0;i<=n;++i)
for (int j=0;j<=n;++j)
{
w[i][j]=0;
c[i][j]=0;
for (int s=0;s<=n;++s)
for (int t=0;t<=n;++t)
{
cin>>p[i][j][s][t];//没法子
}
}
}
void money_get();
void print(int,int);
};
void money::money_get()
{
int i,j;
for (i=1;i<=n;++i)
c[1][i]=0;
for (i=2;i<=n;++i)
for (j=1;j<=n;++j)
{
c[i][j]=-0xfffffff;
if (j>1)
{
c[i][j]=c[i-1][j-1]+p[i-1][j-1][i][j];
w[i][j]=j-1;
}
if(c[i-1][j]+p[i-1][j][i][j]>c[i][j])
{
c[i][j]=c[i-1][j]+p[i-1][j][i][j];
w[i][j]=j;
}
if (j<n&&c[i-1][j+1]+p[i-1][j+1][i][j]>c[i][j])
{
c[i][j]=c[i-1][j+1]+p[i-1][j+1][i][j];
w[i][j]=j+1;
}
}
}
void money::print(int i,int j)
{
if(i>1)
print(i-1,w[i][j]);
cout<<"("<<i<<","<<j<<")"<<" ";
}
int main()
{
money my(4);//数字太多,没有测试,应该没错
my.money_get();
my.print(2,4);
}