![](https://i-blog.csdnimg.cn/blog_migrate/6948aa5717aedbbbdd20d6144ab93637.png)
AX由于只能向右和向下走,所以到达某一坐标只能从上面或左边过来,所以到该坐标的路径数
等于这两点的路径数之和;
值得注意的是,边界上点的路径数最多是一,若前方有障碍,则其后都为0;
#include<stdio.h>longlongmap[25][25]={0};
int xb,yb,xm,ym;
longlong num=0;
int fx[9] = {0, -2, -1, 1, 2, 2, 1, -1, -2};
int fy[9] = {0, 1, 2, 2, 1, -1, -2, -2, -1};
intmain(){
scanf("%d%d%d%d",&xb,&yb,&xm,&ym);
map[0][1]=1;
map[1][0]=1;
map[0][0]=1;
for(int i=0;i<9;i++)
{
if(xm+fx[i]<0||ym+fy[i]<0) continue;
map[xm+fx[i]][ym+fy[i]]=-1;
}
for(int i=1;i<25;i++)
{
if(map[i][0]==-1) map[i][0]=0;
elsemap[i][0]=map[i-1][0];
if(map[0][i]==-1) map[0][i]=0;
elsemap[0][i]=map[0][i-1];
}
for(int i=1;i<=xb;i++)
{
for(int j=1;j<=yb;j++)
{
if(map[i][j]==-1)
{
map[i][j]=0;
continue;
}
map[i][j]=map[i-1][j]+map[i][j-1];
}
}
printf("%lld",map[xb][yb]);
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/86bb3f388d483a602825d6ae28b531e0.png)
对于金字塔中的点f[i][j],只有两点可以到这,即f[i-1][j-1],f[i-1][j].因此要使到达此点的数字之和最大,就要从f[i-1][j-1]和f[i-1][j]中较大的一个过来,这样我们可以用第[i-1]行求出这一行的最大值,由于第一行只有一个数,特殊关照即可,另外,三角形的边上只有一个点可到达,即f[i][1],f[i][i],只能由f[i-1][1]和f[i-1][i-1]加上图中数字得到;
#include<stdio.h>
int max(int x,int y)
{
if(x<y) x=y;
return x;
}
int main()
{
int n,f[1005][1005],num;
scanf("%d%d",&n,&f[1][1]);
for(int i=2;i<=n;i++)
{
scanf("%d",&num);
f[i][1]=num+f[i-1][1];
for(int j=2;j<i;j++)
{
scanf("%d",&num);
f[i][j]=num+max(f[i-1][j],f[i-1][j-1]);
}
scanf("%d",&num);
f[i][i]=num+f[i-1][i-1];
}
for(int i=1;i<=n;i++) num=max(f[n][i],num);
printf("%d",num);
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/253ff6a8e427d06bf10662e5dc5a62a1.png)
![](https://i-blog.csdnimg.cn/blog_migrate/61a2592c16b6cb76c581b11745960c4f.png)
这题和背包的区别仅仅是多了一个失败的经验,首先,胜利的经验一定是比失败高的,所以对于任意对手,比试过后至少会得到losei点经验,若胜利,再得到wini-losei点经验,这样,就和背包问题一模一样,w是药剂量,v是wini-losei,在最后的得分把所有失败的经验加上即可。
#include<stdio.h>
int max(int x,int y)
{
if(x<y) x=y;
return x;
}
int main()
{
int n,x,a,b,sum=0,f[1005]={0},w[1005],v[1005];
scanf("%d%d",&n,&x);
for(int i=1;i<=n;i++)
{
scanf("%d %d %d",&a,&b,&w[i]);
v[i]=b-a;
sum+=a;
}
for(int i=1;i<=n;i++)
{
for(int j=x;j>=w[i];j--)
{
f[j]=max(f[j],f[j-w[i]]+v[i]);
}
}
printf("%lld\n",5*(f[x]+sum));
return 0;
}