关于HDU 2602 ,按照算法课上讲的写了一下
二维:
#include <stdio.h>
#include <string.h>
int n,c;
int v[1001];
int w[1001];
int dp[1001][1001];
int max (int a, int b) {
return (a>b)? a:b;
}
int min(int a, int b) {
return (a>b)? b:a;
}
void knapsack() {
memset(dp,0,sizeof(dp));
int jMax;
for (int i=0; i<=c; ++i) dp[0][i] = 0;
for (int i=1; i<n; ++i) {
jMax = min(w[i]-1, c);
for (int j=0; j<=jMax; ++j) {
dp[i][j] = dp[i-1][j];
}
for (int j=w[i]; j<=c; ++j) {
dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i]);
}
}
dp[n][c] = dp[n-1][c];
if(c>=w[n]) dp[n][c] = max(dp[n][c], dp[n-1][c-w[n]] + v[n]);
}
int main () {
int ncase;
scanf("%d",&ncase);
while (ncase--) {
scanf("%d%d", &n, &c);
for (int i=1; i<=n; ++i) scanf("%d",v+i);
for (int i=1; i<=n; ++i) scanf("%d",w+i);
knapsack();
printf("%d\n",dp[n][c]);
//for (int i=0; i<=n; ++i) {
// for (int j=0; j<=c; ++j) {
// printf("%4d ",dp[i][j]);
// }
// putchar('\n');
//}
}
}
其实对于0-1背包。。一维完全可以解决问题:
#include <stdio.h>
#include <string.h>
int n,c;
int v[1001];
int w[1001];
int dp[1001];
int max(int a, int b) {return a>b? a:b;}
int main () {
int ncase;
scanf("%d",&ncase);
while (ncase--) {
memset(dp,0,sizeof(dp));
scanf("%d%d", &n, &c);
for (int i=1; i<=n; ++i) scanf("%d",v+i);
for (int i=1; i<=n; ++i) scanf("%d",w+i);
for (int i=1; i<=n; ++i)
for (int j=c; j>=w[i]; --j) dp[j] = max(dp[j],dp[j-w[i]] + v[i]);
printf("%d\n",dp[c]);
}
}
典型的 0-1背包问题 还有HDU 1203
#include <stdio.h>
#include <string.h>
int n,m;
int w[10001];
double v[10001];
double dp[10001];
double min(double a, double b) {
return a>b? b:a;
}
int main (){
while (scanf("%d%d",&n,&m),n+m) {
for (int i=0; i<=n; ++i) dp[i] = 1.0;
for (int i=1; i<=m; ++i)
scanf("%d%lf", &w[i], &v[i]);
for (int i=1; i<=m; ++i) {
for (int j=n; j>=w[i]; --j) {
dp[j] = min(dp[j], dp[j-w[i]]*(1.0-v[i]));
}
}
dp[n] = 1.0 - dp[n];
dp[n] *= 100.0;
printf("%.1lf%%\n",dp[n]);
}
}
这题要求至少得到一份的最大概率, 那我们求得不到offer的最小概率即可~ 如代码,01背包 dp存最小概率 , 最后用1减,即可