独立博客: 哲学与程序

哲学与程序

ZOJ@3431

ZOJ@3431
题意:有一n层的城堡,每一层有通往下一层的楼梯。对于第i层,通往下层的楼梯在Xi,Yi处;该层有Mi个宝藏,分别给出其坐标和价值;必须在Ti时刻之前(包括)离开,否则楼梯关闭。开始处在第顶层的X,Y处,且每一个单位时刻内可以走一个单位的距离,只能往上下左右四个方向走,通过楼梯不费时间。问能否在规定时间内离开城堡,如果可以的话输出能获得的最大宝藏价值。
解法:动态规划(DP)。
// 2386571      2011-01-15 16:32:37        Accepted      3431      C++      130      416      redsea
#include<iostream>
#include
<algorithm>
#include
<cstdio>
#include
<string.h>
using namespace std;
struct Floor{
    
int m;
    
int x[8], y[8], value[8];
    
int t[257],v[257];
}p[
105];
int st[105];

int f[2][1205];

inline 
int abs(int a)
{
    
return (a>0?a:-a);
}
int main()
{
    
int T;
    
int x, y, n;
    scanf(
"%d",&T);
    
while(T--)
    {
        scanf(
"%d",&n);
        scanf(
"%d%d",&x,&y);
        p[
0].x[0= x;
        p[
0].y[0= y;
        scanf(
"%d%d",&x,&y);
        p[
0].x[1= x;
        p[
0].y[1= y;
        
for(int i = 1; i < n; i++)
        {
            p[i].x[
0= p[i-1].x[1];
            p[i].y[
0= p[i-1].y[1];
            scanf(
"%d%d",&x,&y);
            p[i].x[
1= x;
            p[i].y[
1= y;
        }
        
for(int i = 0; i < n; i++){
            p[i].value[
0= p[i].value[1= 0;
            scanf(
"%d",&p[i].m);
            
for(int j = 0; j < p[i].m; j++){
                scanf(
"%d%d%d",&p[i].x[2+j], &p[i].y[2+j], &p[i].value[2+j]);
            }
        }
        
for(int i = 0; i < n; i++){
            scanf(
"%d"&st[i]);
        }
        
for(int i = 0; i < n; i++)
            
for(int j = 0; j < 256; j++){
                p[i].t[j] 
= -1;
                p[i].v[j] 
= -1;
            }
        
for(int i = 0; i < n; i++)
        {
            
int a[6], b[9];
            
for(int j = 0; j < p[i].m; j++){
                a[j] 
= j+2;
            }
            p[i].t[
3= abs(p[i].x[0]-p[i].x[1]) + abs(p[i].y[0]-p[i].y[1]);
            p[i].v[
3= 0;
            b[
0= 0;
            
do{
                
for(int j = 0; j < p[i].m; j++)
                {
                    b[j
+1= a[j];
                    b[j
+2= 1;
                    
int value = 0;
                    
int t = 0;
                    
int s = 0;
                    s 
= s | (1<<b[0]);
                    
for(int k = 1; k < j+3; k++){
                        s 
= s|(1<<b[k]);
                        t 
+= abs(p[i].x[b[k]] - p[i].x[b[k-1]]) + abs(p[i].y[b[k]]-p[i].y[b[k-1]]);
                        value 
+= p[i].value[b[k]];
                    }
                    
if(p[i].t[s]<0 || p[i].t[s] > t){
                        p[i].t[s] 
= t;
                        p[i].v[s] 
= value;
                    }
                }
            }
while(next_permutation(a,a+p[i].m));
        }
        memset(f,
-1,sizeof(f));
        f[
0][0= 0;
        
int a = 1, b = 0;
        
for(int i = 0; i < n; i++)
        {
            a 
= 1-a;
            b 
= 1-b;
            
for(int j = 0; j < 256; j++){
                
if(p[i].t[j] < 0 || p[i].v[j] < 0)continue;
                
for(int k = st[i]; k >= 0; k--){
                    
                    
if(f[a][k] >= 0 && k+p[i].t[j] <= st[i] && f[b][k+p[i].t[j]] < f[a][k]+p[i].v[j])
                    
                        f[b][k
+p[i].t[j]] = f[a][k]+p[i].v[j];
                }
            }
            
if(i==0)
                f[a][
0= -1;
            
else{
                
for(int j = 0; j <= st[i-1]; j++)
                    f[a][j] 
= -1;
            }
        }
        
int ans = -1;
        
for(int i = 0; i <= st[n-1]; i++)
        {
            
if(f[b][i]>ans)ans = f[b][i];
        }
        
if(ans>=0)printf("%d\n",ans);
        
else printf("I'm doomed, though I fought bravely\n");
    }
    
return 0;
}

posted on 2011-01-15 16:42 哲学与程序 阅读(225) 评论(0)  编辑 收藏 引用 所属分类: Algorithm


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

公告

欢迎访问 http://zhexue.sinaapp.com

常用链接

随笔分类(37)

随笔档案(41)

Algorithm

最新随笔

搜索

最新评论

独立博客: 哲学与程序