hdu 4501 小明系列故事——买年货
http://acm.hdu.edu.cn/showproblem.php?pid=4501每种商品只能选一次故为01背包。
可以理解为有三个个背包(钱、积分总数、免费领取的件数),某件商品只要满足一种条件即可选取 。
#include <cstdio>
#include <cstring>
#define N 105
#define K 7
int dp[N][N][N][K];
int n, v1, v2, k;
int c1[N], c2[N], val[N];
int max(int x, int y)
{
return x > y ? x : y;
}
int main()
{
while(scanf("%d%d%d%d",&n, &v1, &v2, &k)!=EOF)
{
memset(dp, 0, sizeof(dp));
for(int i=1; i<=n; i++)
{
scanf("%d%d%d", &c1[i], &c2[i], &val[i]);
}
for(int i=1; i<=n; i++)
{
for(int j=0; j<=v1; j++)
{
for(int a=0; a<=v2; a++)
{
for(int b=0; b<=k; b++)
{
int tmp = dp[i-1][j][a][b];
if(j>=c1[i])
tmp = max(tmp, dp[i-1][j-c1[i]][a][b]+val[i]); //开始的bug,原为if(j>=c1[i])tmp = max(dp[i-1][j][a][b], dp[i-1][j-c1[i]][a][b]+val[i]);
if(a>=c2[i])
tmp = max(tmp, dp[i-1][j][a-c2[i]][b]+val[i]);
if(b>=1)
tmp = max(tmp, dp[i-1][j][a][b-1]+val[i]);
dp[i][j][a][b] = tmp;
}
}
}
}
printf("%d ",dp[n][v1][v2][k]);
}
return 0;
}
#include <cstring>
#define N 105
#define K 7
int dp[N][N][N][K];
int n, v1, v2, k;
int c1[N], c2[N], val[N];
int max(int x, int y)
{
return x > y ? x : y;
}
int main()
{
while(scanf("%d%d%d%d",&n, &v1, &v2, &k)!=EOF)
{
memset(dp, 0, sizeof(dp));
for(int i=1; i<=n; i++)
{
scanf("%d%d%d", &c1[i], &c2[i], &val[i]);
}
for(int i=1; i<=n; i++)
{
for(int j=0; j<=v1; j++)
{
for(int a=0; a<=v2; a++)
{
for(int b=0; b<=k; b++)
{
int tmp = dp[i-1][j][a][b];
if(j>=c1[i])
tmp = max(tmp, dp[i-1][j-c1[i]][a][b]+val[i]); //开始的bug,原为if(j>=c1[i])tmp = max(dp[i-1][j][a][b], dp[i-1][j-c1[i]][a][b]+val[i]);
if(a>=c2[i])
tmp = max(tmp, dp[i-1][j][a-c2[i]][b]+val[i]);
if(b>=1)
tmp = max(tmp, dp[i-1][j][a][b-1]+val[i]);
dp[i][j][a][b] = tmp;
}
}
}
}
printf("%d ",dp[n][v1][v2][k]);
}
return 0;
}
hdu 4502 吉哥系列故事——临时工计划
http://acm.hdu.edu.cn/showproblem.php?pid=4502简单贪心。
dp[i]表示前i份工作中第i份必选所获的最大工资。
则dp[i] = max(dp[j] + job[i].c) (job[i].s > job[j].e , 0<= j <i) 。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define N 1005
struct Job
{
int s, e, c;
}job[N];
int dp[N];
int cmp(const void * a, const void * b)
{
struct Job *x = (struct Job *)a;
struct Job *y = (struct Job *)b;
if(x->s == y->s)
return x->e - y->e;
else
return x->s - y->s;
}
int main()
{
int T, n, m, x, y, z, index;
scanf("%d",&T);
while(T--)
{
index = 0;
memset(dp, 0, sizeof(dp));
scanf("%d%d", &m, &n);
for(int i=0; i<n; i++)
{
scanf("%d%d%d",&x, &y, &z);
if(y <= m)
{
job[++index].s = x;
job[index].e = y;
job[index].c = z;
}
}
qsort(job+1, index, sizeof(struct Job), cmp);
job[0].s = job[0].e = job[0].c;
int ans = 0;
for(int i=1; i<=index; i++)
{
for(int j=0; j<i; j++)
{
if(job[i].s > job[j].e && dp[j] + job[i].c > dp[i])
dp[i] = dp[j] + job[i].c;
}
if(ans < dp[i])ans = dp[i];
}
printf("%d ",ans);
}
return 0;
}
#include <cstring>
#include <cstdlib>
#define N 1005
struct Job
{
int s, e, c;
}job[N];
int dp[N];
int cmp(const void * a, const void * b)
{
struct Job *x = (struct Job *)a;
struct Job *y = (struct Job *)b;
if(x->s == y->s)
return x->e - y->e;
else
return x->s - y->s;
}
int main()
{
int T, n, m, x, y, z, index;
scanf("%d",&T);
while(T--)
{
index = 0;
memset(dp, 0, sizeof(dp));
scanf("%d%d", &m, &n);
for(int i=0; i<n; i++)
{
scanf("%d%d%d",&x, &y, &z);
if(y <= m)
{
job[++index].s = x;
job[index].e = y;
job[index].c = z;
}
}
qsort(job+1, index, sizeof(struct Job), cmp);
job[0].s = job[0].e = job[0].c;
int ans = 0;
for(int i=1; i<=index; i++)
{
for(int j=0; j<i; j++)
{
if(job[i].s > job[j].e && dp[j] + job[i].c > dp[i])
dp[i] = dp[j] + job[i].c;
}
if(ans < dp[i])ans = dp[i];
}
printf("%d ",ans);
}
return 0;
}
hdu 4504 威威猫系列故事——篮球梦
http://acm.hdu.edu.cn/showproblem.php?pid=4504组合题。
a为要拿的分数,n为可以得分的轮数(每轮从1、2、3中取值)
(1)a<=n :ans = 3^n;
(2)a>3*n: ans = 0;
(3)n<a<=3*n: 得分q可取 a <=q<=3*n
另q=q-n,问题转化为把q分成k1个1,k2个2并在n个位子中选位插入的情况种数。 注意k1+k2<=n。
枚举一遍即可。
#include <iostream>
using namespace std;
long long C(long long n, long long a)
{
if(2*a>n)
a = n - a;
long long ret = 1;
for(int i=0; i<a; i++)
ret *= n - i;
for(int i=0; i<a; i++)
ret /= a - i;
return ret;
}
int main()
{
long long a, b, t, n, k;
while(cin >> a >> b >> t)
{
long long ans = 0;
a = b - a;
t = t / 15;
a += t / 2 + 1;
n = ( t + 1 ) / 2;
if(a<=n)
{
ans = 1;
for(long long i=1; i<=n; i++)
ans *= 3;
}
else if(a > 3*n)
ans = 0;
else
{
for(long long q=a; q<=3*n; q++)
{
long long tmp = q;
tmp -= n;
k = tmp / 2;//最多k个2
for(long long i=0; i<=k; i++)
{
long long j = tmp - 2 * i;
if(i+j>n) continue;
ans += C(n, i) * C(n-i, j);
}
}
}
cout << ans << endl;
}
return 0;
}
using namespace std;
long long C(long long n, long long a)
{
if(2*a>n)
a = n - a;
long long ret = 1;
for(int i=0; i<a; i++)
ret *= n - i;
for(int i=0; i<a; i++)
ret /= a - i;
return ret;
}
int main()
{
long long a, b, t, n, k;
while(cin >> a >> b >> t)
{
long long ans = 0;
a = b - a;
t = t / 15;
a += t / 2 + 1;
n = ( t + 1 ) / 2;
if(a<=n)
{
ans = 1;
for(long long i=1; i<=n; i++)
ans *= 3;
}
else if(a > 3*n)
ans = 0;
else
{
for(long long q=a; q<=3*n; q++)
{
long long tmp = q;
tmp -= n;
k = tmp / 2;//最多k个2
for(long long i=0; i<=k; i++)
{
long long j = tmp - 2 * i;
if(i+j>n) continue;
ans += C(n, i) * C(n-i, j);
}
}
}
cout << ans << endl;
}
return 0;
}