TopCoder SRM667 250

        这个题说的是,有n个长度为m的01串,按一定顺序填到对应的m个坑里,假设某次填坑,有k个坑之前没填过1,那么就会产生k*k的花费。问如何安排顺序使得花费最少。

        dp。其实每次填坑,花费和填坑顺序没有太大关系,只需要关心之前哪些坑被填过1就行了。从另一个角度理解,其实不一定要填完n个串,只需要填上n个串出现过的所有1就可以了。那么就可以弄一个m位二进制来dp,外循环是坑的状态,内循环扫一遍所有串,尝试填进去。

        现在打TC的div1还真是吃力。。基本都是爆零。今天摸索了一会才知道如何在practice room里测题。

// BEGIN CUT HERE

// END CUT HERE
#line 5 "OrderOfOperations.cpp"
#include <string>
#include <vector>
#include <bitset>
#include <iostream>

using namespace std;

int dp[1050000];
const int INF = 1000000000;

int fun(vector<string> s){
    int n=s.size();
    if(n==0)return 0;
    int m=s[0].size();
    int t=1<<m;
    for(int i=0;i<t;i++){
        dp[i]=INF;
    }
    int val[n+10];
    for(int i=0;i<n;i++){
        bitset<20> b(s[i]);
        val[i]=b.to_ulong();
    }
    dp[0]=0;
    for(int i=0;i<t;i++){
        for(int j=0;j<n;j++){
            int res=i|val[j];
            int NEW=val[j]&(~i);
            bitset<20> tmp(NEW);
            NEW=tmp.count();
            dp[res]=min(dp[res],dp[i]+NEW*NEW);
        }
    }
    int all=0;
    for(int i=0;i<n;i++){
        all|=val[i];
    }
    return dp[all];
}

class OrderOfOperations {
	public:
	int minTime(vector <string> s) {
        return fun(s);
	}
};


你可能感兴趣的:(TopCoder SRM667 250)