Jeanny
寂兮,寥兮,独立不改,周行而不殆

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);
    }
    //为什么不是把东西全吃了,活的最多?
	//因为到下一次吃东西,还要消耗时间/体力 
}

背包-中

飞扬的小鸟

飞扬的小鸟

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=10000+10;
const int maxm=2000+10;
int n,m,p;
int x[maxn],y[maxn];   //i位置,上升x[i],下降y[i] 
int low[maxn],high[maxn];   //i位置能通过的范围是low[i]-high[i] 
int f[maxn][maxm];   //到(i,j)的最少点击次数 
int e[maxn];    //e[i]表示i位置有没有管道 
int main() {
    scanf("%d%d%d",&n,&m,&p);
    for(int i=1; i<=n; ++i) scanf("%d%d",&x[i],&y[i]);
    for(int i=1; i<=n; ++i) {
        low[i]=0;
        high[i]=m+1;
    }
    int a,b,c,t = 0;
    for(int i=1; i<=p; ++i) {
        scanf("%d%d%d",&a,&b,&c);
        e[a]=1;
        low[a]=b;
        high[a]=c;
    }
    memset(f,0x3f,sizeof(f));
    for(int i=1; i<=m; ++i) f[0][i]=0;
    for(int i=1; i<=n; ++i) {
        for(int j=x[i]+1; j<=m+x[i]; ++j)//前一步是可以达到m-x[i]中间的高度的 
            f[i][j]=min(f[i-1][j-x[i]]+1,f[i][j-x[i]]+1);
        for(int j=m+1; j<=m+x[i]; ++j)
            f[i][m]=min(f[i][m],f[i][j]);//天花板 
        for(int j=1; j<=m-y[i]; ++j)
            f[i][j]=min(f[i][j],f[i-1][j+y[i]]);//下降 
        for(int j=1; j<=low[i]; ++j)
            f[i][j]=f[0][0];  
        for(int j=high[i]; j<=m; ++j)
            f[i][j]=f[0][0]; 
    }
    int ans=f[0][0];
    for(int j=1;j<=m;++j) {
        ans=min(ans,f[n][j]);
    }
    int fl = 0;
    if(ans<f[0][0]) printf("1\n%d\n",ans);
    else{
    	int i,j; ans = 0;
        for(i=n;i>=1;i--) {//倒着,当这个是管道,且可以通过的时候,打标记 
        	if(!e[i]) continue;
            for(j=1;j<=m;++j) {
                if(f[i][j]<f[0][0]){
                	fl = i;
                	break;
				} 
            }
    		if(fl) break;
        }
        for(int i = 1; i <= fl; i++){//因为输入不是按照从小到大的顺序,因此只能数管道个数 
        	if(e[i]) ans++;
		} 
		printf("0\n%d\n",ans);
    }
    return 0;
}

P1364 医院设置 换根dp入门

//自下而上求每个子树到它的距离
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
int n, g[105], f[105], cnt, hd[105], sum[105], a[105], mx, ans;
struct Edge{
    int to, nxt;
}edge[205];
void add(int u, int v){
    cnt++;
    edge[cnt].to = v;
    edge[cnt].nxt = hd[u];
    hd[u] = cnt;
}
void dfs(int u, int fa){
    sum[u] = a[u];
    for(int i = hd[u]; i; i = edge[i].nxt){
        int v = edge[i].to;
        if(v == fa) continue;
        dfs(v, u);
        sum[u] += sum[v];
        f[u] += f[v] + sum[v];
    }
}
void dfs1(int u, int fa){//换根
    for(int i = hd[u]; i; i = edge[i].nxt){
        int v = edge[i].to;
        if(v == fa) continue;
        g[v] = g[u] - sum[v] + (mx - sum[v]) ;
        ans = min(ans, g[v]);
        dfs1(v, u);
    }
}
int main(){
    scanf("%d",&n); int x,y;
    for(int i = 1; i <= n; i++){
        scanf("%d%d%d",&a[i],&x,&y);
        add(i, x); add(i, y);
        mx += a[i];
    }
    dfs(1, 0);
    g[1] = f[1];
    ans = f[1];
    dfs1(1, 0);
    // for(int i = 1; i <= n; i++)
    //     cout<<"hhh: "<<i<<" "<<g[i]<<endl;
    printf("%d\n",ans);
    return 0;
}

posted on 2020-10-10 20:23  Jeanny  阅读(211)  评论(0)    收藏  举报