hdu1176免费馅饼
比较无语的一个题、、、、、、、、、、
题意:gameboy每秒仅能移动一米,馅饼落在0-10m范围内,求能捡到的最多馅饼数。
写了个常规的DP动态方程,改来改去还是Time Limited Exceed 伤心呀 ~~~~然而的然而,学习了一下qsort的cmp函数写法。
对于结构体比较函数,写法为:t从小打到排列,x从大到小排列
int compare(const void *a,const void *b)//参数必须写成这个形式
{
struct info *c=(info *)a;
struct info *d=(info *)b;
if(c->t!=d->t) return c->t-d->t;
else return d->x-c->x;
}
言归正传,开始的思路是,开辟一个数组存放每个馅饼的掉落信息(悲剧就是这么发生的,唉~~).对馅饼的信息进行排序,时间小的在前,时间相等的坐标小的在前。
然后DP(该馅饼加上前面可达的馅饼中最多的馅饼数)、自认为思想很正确,但无疑不能AC,超时,尽管用了qsort。
额、、、比较难为情的是,我又看解题报告了(面壁思过了,已经).
这个题可以理解成数塔,看到这句话 我就看到了希望,是呀~~~~~巨轻松。。。。。
在这里我要警醒自己,换位思考、、、、、如果正着走不顺当,那就反过来走走试试 ,也许就是守得云开见月明啦
好啦 代码:
#include<string>
#include<stdio.h>
int num[100002][13];
int max(int a,int b,int c)
{
if(a>=b&&a>=c) return a;
else if(b>=a&&b>=c) return b;
else return c;
}
int main()
{
int n;
while(scanf("%d",&n)&&n!=0)
{
memset(num,0,sizeof(num));
int i=0,j;
int x,t;
int MaxT=0;
for(;i<n;i++)
{
scanf("%d%d",&x,&t);
num[t][x+1]++;
if(MaxT<t) MaxT=t;
}
从下向上DP。多美妙的思想吖
for(i=MaxT-1;i>=0;i--)
{
for(j=11;j>0;j--)
{
num[i][j]+=max(num[i+1][j-1],num[i+1][j],num[i+1][j+1]);
}
}
printf("%d\n",num[0][6]);
}
return 0;
}
hdu2571命运
经典的DP。
题意从1,1到达m,n点能途径的最大值。
注意初始化,有负值,所以初始化的时候要初始化为最小值-(m+n)*K=-102000;
对于DP[i][j],有三种到达方式:DP[i-1][j],DP[i][j-1],DP[i][k](k为j的因子)
代码:
#include<string>
#include<stdio.h>
int num[21][1005];
int sum[21][1002];
int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
int m,t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&m,&n);
int i=0,j,k;
for(i=1;i<=m;i++)
{
for(j=1;j<=n;j++)
scanf("%d",&num[i][j]);
}
for(int i=0;i<=m;i++) sum[i][0]=-1000000; //***初始化
for(int j=0;j<=n;j++) sum[0][j]=-1000000;//****初始化
sum[1][0]=0;sum[0][1]=0;//1,1点不需要最小值
int mm;
for(i=1;i<=m;i++)
{
for(j=1;j<=n;j++)
{
sum[i][j]=num[i][j];
mm=max(sum[i-1][j],sum[i][j-1]);
for(k=1;k<j;k++)
{
if(j%k==0&&mm<sum[i][k]) mm=sum[i][k];
}
sum[i][j]+=mm;
}
}
printf("%d\n",sum[m][n]);
}
return 0;
}