2016年3月10日 星期四

USACO 2015 January Contest, Gold Problem 2. Moovie Mooving [位元dp]

http://www.usaco.org/index.php?page=viewproblem2&cpid=515

我當初看的時候,也不知道題目再做什麼

再想想,就發現好像是bitmask的dp!!!

於是,就開了dp[1<<MAX_N][MAX_N]陣列,紀錄1<<MAX_N最後是MAX_N最長可以延伸到哪裡。

但是,不幸的很,TLE了!!

後來想想,後面那個維度根本用不到!!!(之前做bitmask有用到所以就不小心在腦海中留下不好印象XDD)

於是,就AC了


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;

const int MAX_N = 21;
vector <int> C[MAX_N];
int t[MAX_N];
int dp[(1<<MAX_N)];
int n,l;

int count_bit(int x) {
    int ret=0;
    while (x>0) {
        if (x!=(x/2)+(x/2)) ret++;
        x/=2;
    }
    return ret;
}

int get_dp(int i,int j) {   //i-->which n , j-->dp_val
//    cout << "get " << i << " and " << j << endl;
    int tmp=j;
    int id=lower_bound(C[i].begin(),C[i].end(),tmp) - C[i].begin();
    
    if (C[i][id]!=j) id--;
//    cout<<"("<<j<<" vs "<<C[i][id]<<")";
    if (C[i][id]==-1) return 0;
//    puts("still alive ");
    return max(C[i][id]+t[i] , j);
}

int main () {
    if (fopen("movie.in","r")) {
        freopen("movie.in","r",stdin);
        freopen("movie.out","w",stdout);
    }
    
    int k,qq;
    while (scanf("%d %d",&n,&l) != EOF) {
        for (int x=0;n>x;x++) {
            scanf("%d %d",&t[x],&k);
            C[x].clear();
            C[x].push_back(-1);
            for (int y=0;k>y;y++) {
                scanf("%d",&qq);
                C[x].push_back(qq);
            }
        }
        memset(dp,0,sizeof(dp));
        //bitmask DP
        for (int i=0;n>i;i++) {
            dp[(1<<i)]=get_dp(i,0);
        }
        
        for (int x=1;(1<<n)>=x;x++) {
            int tmp=x;
            int i=0;
            
            for (int j=0;n>j;j++) {
                if (((1<<j)|x)!=x)dp[((1<<j)|x)]=max(dp[((1<<j)|x)],get_dp(j,dp[x]));
            }
                
    
//            cout<<"x="<<x<<" : "<<count_bit(x)<<endl;
        }
        int ans=19343;
        for (int x=0;(1<<n)>=x;x++) {
//            cout << "x = " <<x << " : ";
            for (int y=0;1>y;y++) {
                if (dp[x]>=l && count_bit(x)<ans) ans=count_bit(x);
//                cout<<dp[x][y] << ' ';
            }
//            cout << endl;
        }
        printf("%d\n",(ans==19343?-1:ans));
    }
}


沒有留言:

張貼留言