zoukankan      html  css  js  c++  java
  • POJ 1015


    新赛季的开始!

    (POJ 1015)

    前言

    (dp) 一般是用于求解最后的值,这个 (dp) 不同于以往的 (dp) ,它需要求解之前的状态,在 (dp) 状态转移的过程中,它的结果总是在不断地移动,在求解完之后,搜索之前的状态时,前面的值已经发生改变,所以需要在状态转移的时候就应该对结果进行保存,这也就是这个题的坑之处,写了一下午。

    题解

    这个题是一个背包问题,也不能说是背包就是的一些状态转移类型,比较容易理解,坑就在于搜索解。

    [dp[i][j] = max(dp[i-(l[k]-r[k])][j-1]) ]

    这个状态转移方程就是根据之前的结果对于添加这个物品之后状态求解最小值,在求解的过程中趁机对物品状态进行保存,然后特别注意一个样例

    输入

    1 1
    0 0 
    0 0
    

    输出

    Jury #1
    Best jury has value 0 for prosecution and value 0 for defence:
     1
    
    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int MAXN = 2e3+5;
    int vis[MAXN][21],dis[MAXN][21];
    int l[205],r[205];
    int sum[MAXN][21][2];
    vector<int>v[MAXN][21];
    inline int min(int a,int b){return a<b?a:b;}
    // inline int abs(int a){return a<0?-a:a;}
    void slove(int x,int y,int dx,int dy){
    	v[dx][dy].clear();
    	for(int i=0;i<(int)v[x][y].size();++i)
    		v[dx][dy].push_back(v[x][y][i]);
    	sum[dx][dy][0]=sum[x][y][0];
    	sum[dx][dy][1]=sum[x][y][1];
    }
    int main(){
    	int n,m,times=1;
    	while(scanf("%d%d",&n,&m)!=EOF&&(n+m)){
    		memset(vis,0,sizeof(vis));
    		memset(dis,0,sizeof(dis));
    		memset(sum,0,sizeof(sum));
    		vis[400][0]=1;
    		for(int i=1;i<=n;++i){
    			scanf("%d%d",&l[i],&r[i]);
    			int d=l[i]-r[i];	
    			for(int j=m;j>0;--j){
    				for(int k=0;k<=800;++k){
    					if(k+d>=0&&d+k<=800&&vis[k][j-1]){
    						if(dis[k+d][j]<=dis[k][j-1]+r[i]+l[i]){
    							vis[k+d][j]=i;
    							dis[k+d][j]=dis[k][j-1]+r[i]+l[i];
    							slove(k,j-1,k+d,j);
    							v[k+d][j].push_back(i);
    							sum[k+d][j][0]+=l[i];
    							sum[k+d][j][1]+=r[i];
    							// printf("%d
    ",k+d);
    							// for(int b=0;b<(int)v[k+d].size();++b)
    							// 	printf("%d ",v[k+d][b]);
    							// printf("
    ");
    						}
    					}
    				}
    			}
    		}
    		// printf("%d
    ",vis[400][1]);
    		int minn=2000,L=0,R=0;
    		for(int i=0;i<=1000;++i){
    			if(vis[i][m]){
    				if(abs(minn)==abs(i-400)){
    					if(L+R<=sum[i][m][0]+sum[i][m][1]){
    						L=sum[i][m][0];
    						R=sum[i][m][1];
    						minn=i-400;
    					}
    				}
    				if(abs(minn)>abs(i-400)){
    					minn=i-400;
    					L=sum[i][m][0];
    					R=sum[i][m][1];
    				}
    			}
    		}
    		printf("Jury #%d 
    Best jury has value %d for prosecution and value %d for defence: 
    ",times,L,R);
    		for(int i=0;i<(int)v[minn+400][m].size();++i)
    			printf(" %d",v[minn+400][m][i]);
    		printf("
    
    ");
    		++times;
    	}
    	return 0;
    }
    
    新赛季的开始
  • 相关阅读:
    Vue路由机制
    谷歌浏览器打不开应用商店的解决方法
    Vue报错——Component template should contain exactly one root element. If you are using vif on multiple elements, use velseif to chain them instead.
    Vue.js学习之——安装
    Vue使用axios无法读取data的解决办法
    关于localstorage存储JSON对象的问题
    2013年整体计划
    个人喜欢的警语收集
    Linux防火墙的关闭和开启
    Flex修改title 转载
  • 原文地址:https://www.cnblogs.com/VagrantAC/p/12739526.html
Copyright © 2011-2022 走看看