通过数: 1
250:
裸的多重背包,次数是min{budget / cost[i]的下界,tim[i]},即最多能降多少时间,代价是cost[i]
现场忘了照着版调了一阵。
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
class FarmvilleDiv2 {
public:
int minTime(vector <int>, vector <int>, int);
};
const int MAXN = 5000 + 5;
int dp[MAXN];
void zerobag(int w, int v, int budget)
{
for(int i = budget - w; i >= 0 ; i--){
if(dp[i] != -1) dp[i + w] = max(dp[w + i], dp[i] + v);
}
}
void totbag(int w, int v, int budget)
{
for(int i = 0 ; i <= budget - w ; i++){
if(dp[i] != -1) dp[i + w] = max(dp[i + w], dp[i] + v);
}
}
void multibag(int num, int w, int budget)
{
if(num * w >= budget)
totbag(w, 1, budget);
else{
int k = 1;
while(k < num){
zerobag(k * w, k, budget);
num -= k;
k = k * 2;
}
}
}
int FarmvilleDiv2::minTime(vector <int> time, vector <int> cost, int budget) {
int n = time.size();
for(int i = 0 ; i <= budget ; i++) dp[i] = -1;
dp[0] = 0;
int sum = 0;
for(int i = 0 ; i < n ; i++){
sum += time[i];
multibag(min(budget / cost[i], time[i]), cost[i], budget);
}
int temp = 0;
for(int i = 0 ; i <= budget ; i++) temp = max(temp, dp[i]);
return max(sum - temp, 0);
}
<%:testing-code%>
//Powered by [KawigiEdit] 2.0!
550:
乍一看以为是博弈,仔细一想就是分类讨论。
因为走出去又可以走回来,所以一旦周围距离起始点的位置3以内的地方没有特殊点(比如障碍和出口),就可以判断出答案了。
直接讨论Alice输的情况。
情况一:Alice的初始位置周围都是障碍,动弹不得输掉
情况二:Alice任意的走出合法一步,这个格子旁边都有一个出口
情况三:总步数是偶数
但是其实还要注意Alice马上就赢的情况,这种情况高于前面输的情况
情况一:Alice的起点旁边就有出口
情况二:k=1
然而现场漏了k=1的情况……
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
class BoardEscapeDiv2 {
public:
string findWinner(vector <string>, int);
};
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
int r, c;
bool valid(int x, int y)
{
if(x < 0 || x >= r) return false;
if(y < 0 || y >= c) return false;
return true;
}
bool check1(int x, int y, vector <string>s)
{
for(int i = 0 ; i < 4 ; i++){
int tx = x + dx[i];
int ty = y + dy[i];
if(valid(tx, ty) && s[tx][ty] != '#'){
if(s[tx][ty] == '.') return true;
}
}
return false;
}
bool check3(int x, int y, vector <string> s)
{
int ok = 0;
for(int i = 0 ; i < 4 ; i++){
int tx = x + dx[i], ty = y + dy[i];
if(valid(tx, ty) && s[tx][ty] == 'E'){
return true;
}
}
return false;
}
bool check2(int x, int y, vector <string> s)
{
int ok = 0;
for(int i = 0 ; i < 4 ; i++){
int tx = x + dx[i];
int ty = y + dy[i];
if(valid(tx, ty) && s[tx][ty] != '#'){
if(!check3(tx, ty, s)){
return true;
}
}
}
return false;
}
string BoardEscapeDiv2::findWinner(vector <string> s, int k) {
r = s.size(), c = s[0].size();
int x, y;
x = y = -1;
for(int i = 0 ; i < r ; i++){
for(int j = 0 ; j < c ; j++){
if(s[i][j] == 'T'){
x = i, y = j;
break;
}
}
if(x != -1) break;
}
string s1 = "Alice";
string s2 = "Bob";
for(int i = 0 ; i < 4 ; i++){
int tx = x + dx[i], ty = y + dy[i];
if(valid(tx, ty) && s[tx][ty] == 'E'){
return s1;
}
}
if(!check1(x, y, s) && k != 1) return s2;
if(!check2(x, y, s)) return s2;
if(k % 2 == 0) return s2;
return s1;
}
<%:testing-code%>
//Powered by [KawigiEdit] 2.0!