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