Entries

スポンサーサイト (この記事を編集する[管理者用])

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

コメント

コメントの投稿

コメントの投稿
管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://rsujskf.blog32.fc2.com/tb.php/1591-904b4d60
この記事にトラックバックする(FC2ブログユーザー)

SRM483 DIV1 MEDIUM - Bribes (この記事を編集する[管理者用])

Source

TopCoder SRM483 DIV1 MEDIUM (500pt)
Problem Statement
SRM483 DIV1 自分の参加記録

問題概要

50人以下の人が直線上に並んでいて,それぞれの人のHPと攻撃力が与えられる.
何人か選んで,k番目の人を選んだら,
 i番目の人のHPを floor(攻撃力[k] / 2^|i-k|) だけ減らす.
最小で何人選べば,全員のHPを0以下にできるか求める問題.できないならそれを指摘する.
HPと攻撃力は500以下.

解法

高々左右8人までしか影響を及ぼさないので,自分と左右8人,計17人を選ぶかどうかを状態としてDPする.
状態数は,n*2^17.

C++によるスパゲッティなソースコード

このコードは実際に本番でサブミットしたコードです.見にくいと思われます.

// #includeとusing namespace std;は略

#define REP(i,a,b) for(i=a;i<b;i++)
#define rep(i,n) REP(i,0,n)

#define N 8
#define INF 10000000

int n;
int mm;
int dp[75][132001];
int hp[55], att[55];

int ab(int x){if(x<0)return -x; return x;}

int solve(int st,int mask){
  int i,j,k;
  int res = INF;

  if(dp[st][mask]>=0) return dp[st][mask];
  if(st-N-1 >= n) return dp[st][mask]=0;
  
  if(st-N-1 >= 0){
    k=0;
    rep(i,2*N+1) if(mask&1<<i) k += (att[st-i-1] / (1<<(ab(N-i))));
    if(k < hp[st-N-1]) return dp[st][mask]=INF;
  }

  rep(i,2){
    k = solve(st+1,((mask<<1)+i)&mm)+i;
    if(k < res) res = k;
    if(st>=n) break;
  }

  return dp[st][mask]=res;
}

class Bribes {
public:
int minBribes(vector <int> influence, vector <int> resistance) {
  int i,j,k;
  int res;

  mm = (1<<(2*N+1))-1;

  n=influence.size();
  rep(i,n) hp[i] = resistance[i], att[i] = influence[i];

  rep(i,75) rep(j,132001) dp[i][j]=-1;
  res = solve(0,0);

  if(res>=INF) res = -1;
  return res;
}

};

コメント

コメントの投稿

コメントの投稿
管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://rsujskf.blog32.fc2.com/tb.php/1591-904b4d60
この記事にトラックバックする(FC2ブログユーザー)

Appendix

Recent Articles

ブログ内検索

Ads


(プライバシーポリシー)
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。