HDU4500:小Q系列故事——屌丝的逆袭
参考思路:模拟。
参考程序:
#include<cstdio>
#include<cstring>
const int maxN = 20 + 2;
int N, M;
int maze[maxN][maxN];
int dir[4][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0} };
int ok(int x, int y) { return x >= 0 && y >= 0 && x < N && y < M; }
int cAbs(int x) { return x > 0 ? x : (-x); }
int main()
{
while( scanf("%d %d", &N, &M) == 2 ) {
if( N == 0 && M == 0 ) break;
for(int i = 0; i < N; i ++)
for(int j = 0; j < M; j ++)
scanf("%d", maze[i] + j);
int res = -1000000007, row = 0, col = 0;
for(int i = 0; i < N; i ++) {
for(int j = 0; j < M; j ++) {
//if( maze[i][j] > 0 ) continue;
int val = 0;
for(int k = 0; k < 4; k ++) {
int u = i + dir[k][0];
int v = j + dir[k][1];
if( ok(u, v) ) {
if( maze[u][v] * maze[i][j] < 0 )
val += cAbs(maze[u][v]);
else
if( maze[u][v] * maze[i][j] > 0 )
val -= cAbs(maze[u][v]);
}
}
if( val > res ) {
res = val;
row = i; col = j;
}
}
}
printf("%d %d %d\n", row + 1, col + 1, res);
}
return 0;
}
HDU4501:小明系列故事——买年货
参考思路:用最赤裸裸的DP可以过。
参考程序:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxN = 100 + 2;
const int maxK = 5 + 2;
int dp[maxN][maxN][maxN][maxK];
int N, V1, V2, K;
int a[maxN], b[maxN], v[maxN];
int main()
{
while( scanf("%d %d %d %d", &N, &V1, &V2, &K) == 4 ) {
for(int i = 1; i <= N; i ++)
scanf("%d %d %d", a + i, b + i, v + i);
memset(dp, 0, sizeof(dp));
for(int i = 1; i <= N; i ++) {
for(int j = 0; j <= V1; j ++) {
for(int k = 0; k <= V2; k ++) {
for(int r = 0; r <= K; r ++) {
dp[i][j][k][r] = dp[i - 1][j][k][r];
if( j >= a[i] )
dp[i][j][k][r] = max(dp[i][j][k][r], v[i] + dp[i - 1][j - a[i]][k][r]);
if( k >= b[i] )
dp[i][j][k][r] = max(dp[i][j][k][r], v[i] + dp[i - 1][j][k - b[i]][r]);
if( r >= 1 )
dp[i][j][k][r] = max(dp[i][j][k][r], v[i] + dp[i - 1][j][k][r - 1]);
}
}
}
}
printf("%d\n", dp[N][V1][V2][K]);
}
return 0;
}
HDU4502:吉哥系列故事——临时工计划
参考思路:DP[ cur_time ] = max { DP[ cur_time - 1 ], DP[ pre_time ] + C[ someone_from_s_to_e ] }
参考程序:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxN = 100 + 2;
int M;
struct node
{
int s, e, c;
inline bool operator<(const node &cp) const {
if( e != cp.e ) return e < cp.e;
return s < cp.s;
}
inline void in() { scanf("%d %d %d", &s, &e, &c); }
};
node A[maxN * 10]; int nA;
int dp[maxN];
int main()
{
int nt; scanf("%d", &nt);
while( (nt --) > 0 ) {
scanf("%d %d", &M, &nA);
for(int i = 0; i < nA; i ++) A[i].in();
sort(A, A + nA); memset(dp, 0, sizeof(dp));
int pd = 0, res = 0;
for(int ti = 1; ti <= M; ti ++) {
int cnt = 0;
while( pd < nA && A[pd].e <= ti ) {
cnt = max(cnt, dp[A[pd].s - 1] + A[pd].c);
pd ++;
}
dp[ti] = max(cnt, dp[ti - 1]); res = max(res, dp[ti]);
}
printf("%d\n", res);
}
return 0;
}
HDU4503:湫湫系列故事——植树节
参考思路:考虑不合法的状态描述:只有两个小朋友是朋友。对于当前小朋友A,假设他有NA个朋友,那么如果A在这3个小朋友当中,那么不合法的状态有:NA * (total - NA - 1)个,其中,total表示总的小朋友个数。对于每一个小朋友都这么计算,得到“总的不合法状态数目”,注意,这里的“总的不合法状态数目”重复1次,所以,需要再除以2。原因在于:假设A和B是好朋友,而C与A、C与B都不是好朋友,那么在计算A和B时,状态<A, B, C>会被计算2次。
参考程序:
#include<cstdio>
#include<cstring>
const int maxN = 1000 + 2;
int d[maxN]; int N;
int main()
{
int nt; scanf("%d", &nt);
while( (nt --) > 0 ) {
scanf("%d", &N);
for(int i = 0; i < N; i ++) scanf("%d", d + i);
int total = N * (N - 1) * (N - 2) / 6;
int sub = 0;
for(int i = 0; i < N; i ++) sub += d[i] * (N - 1 - d[i]);
sub >>= 1; //printf("%d %d\n", total, sub);
printf("%.3lf\n", (total - sub + 0.0) / total);
}
return 0;
}
HDU4504:威威猫系列故事——篮球梦
参考思路:
建立最终需要满足的不等式:
A_score = A + Sa(1) + Sa(2) + ... + Sa(times_A) > B_Score = B + Sb(1) + Sb(2) + ... + Sb(times_B)
表达的含义是:最终A的得分比B高,其中,Sa(i)表示A的某一场进攻得分,Sb(i)同理;times_A、times_B分别表示A和B可进攻的总次数。
根据题意,化简可得:
Sa(1) + Sa(2) + ... + Sa(times_A) > B + times_B - A
且有:times_B = (t / 15) / 2 和 times_A = (t / 15) - times_B。考虑到A最多进攻20次,枚举计数即可。
参考程序:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int A, B, t, na, nb;
unsigned int dp[20 + 2][60 + 2];
void init()
{
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for(int i = 1; i <= 20; i ++) {
for(int j = 0; j <= 60; j ++) {
if( j > 3 * i ) break;
if( j >= 1 ) dp[i][j] += dp[i - 1][j - 1];
if( j >= 2 ) dp[i][j] += dp[i - 1][j - 2];
if( j >= 3 ) dp[i][j] += dp[i - 1][j - 3];
}
}
}
int main()
{
init();
while( scanf("%d %d %d", &A, &B, &t) == 3 ) {
int na = (t / 15 + 1) / 2;
int nb = (t / 15) - na;
// A + x1 + x2 + ... xna > B + nb
// x1 + x2 + ... + xna > B + nb - A
int left = B + nb - A;
if( left > 3 * na ) printf("0\n");
else {
unsigned int res = 0;
for(int i = max(left + 1, 0); i <= (3 * na); i ++)
res += dp[na][i];
printf("%u\n", res);
}
}
return 0;
}
OpenSpirit @ SWJTU