1. 程式人生 > 實用技巧 >基礎dp

基礎dp

P1156 垃圾陷阱

f[i][j]表示前i個垃圾填j的高度的最大維持時間,一開始覺得這個方程式可以都用來吃從而得到最大時間,但是忘記了j在迴圈。

#include <bits/stdc++.h>
#include <algorithm>
using namespace std;
#define maxn 1001
#define INF 0x7f7f7f7f
#define max(x,y) x>y?x:y
int f[101][1001],sum;
struct arr{
    int x,t,h;
}a[maxn];
int cmp(arr a,arr b){
    return a.x<b.x;
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for (int i=1;i<=m;i++){
    	scanf("%d%d%d",&a[i].x,&a[i].t,&a[i].h);
    	sum+=a[i].t;
	}
   
    sort(a+1,a+m+1,cmp);
    memset(f,0xA0,sizeof f);
    f[0][0]=10; a[0].x=a[0].t=a[0].h=0;
    int fl=0;
    //正的去推正的,這樣得出的結果 
	// 負的可能推出正的,從而達到頂端 
    for (int i=1;i<=m;i++)
    {
        for (int j=0;j<=n;j++)
        {
            if (f[i-1][j]-a[i].x+a[i-1].x>=0) 
                f[i][j]=max(f[i][j],f[i-1][j]-a[i].x+a[i-1].x+a[i].t);
            if (f[i-1][j-a[i].h]-a[i].x+a[i-1].x>=0 && j-a[i].h>=0)
			//error if(j-a[i].h>=0) 
                f[i][j]=max(f[i][j],f[i-1][j-a[i].h]-a[i].x+a[i-1].x);
            if (f[i][j]>=0 && j==n){
                printf("%d\n",a[i].x);
                fl=1;
                return 0;	
            }
        }
    }  
    int ans=0;
    if (!fl){
		for(int i=1;i<=m;i++) 
			if(f[i][0]>0){
				ans=max(ans,f[i][0]+a[i].x);//在第a[i].x 秒時獲得的最大能量,加上之前的a[i].x就是存活時間 
			}	
		//還能存活的時間+已經存活的時間 a[i].x 
		printf("%d\n",ans);
    }
    //為什麼不是把東西全吃了,活的最多?
	//因為到下一次吃東西,還要消耗時間/體力 
}