2.7总结

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;
}

对于金字塔中的点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;
}

这题和背包的区别仅仅是多了一个失败的经验,首先,胜利的经验一定是比失败高的,所以对于任意对手,比试过后至少会得到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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值