TopCoder SRM667 250

来源:互联网 发布:越南废除汉字 知乎 编辑:程序博客网 时间:2024/05/28 15:16

        这个题说的是,有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);}};


0 0