hdu 1248
水题额
int dp[N], v[] = {150, 200, 350};
void Init()
{
for(int i = 1;i < N;++i)
for(int j = 0;j < 3;++j)
if(i >= v[j])
dp[i] = max(dp[i], dp[i-v[j]]+v[j]);
}
int main()
{
Init();
int T;cin >> T;
while(T--)
{
int n;cin >> n;
cout << n - dp[n] << endl;
}
return 0;
}
hdu 1114
题意:T组样例,每组给重量空罐重量a,最后重量b,下面n组硬币规格,价值+重量,完全背包模板
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <sstream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <iomanip>
#include <stack>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int N = 1e6 + 100;
const int MOD = 1e9 + 9;
#define lson l, m, rt << 14
#define rson m + 1, r, rt << 1 | 1
#define F(i, l, r) for(int i = l;i <= (r);++i)
#define RF(i, l, r) for(int i = l;i >= (r);--i)
int dp[N], v[N], w[N];
int main()
{
int T;cin >> T;
while(T--)
{
memset(dp, 0x3f, sizeof(dp));
int a, b;cin >> a >> b;b -= a;
int n;cin >> n;
F(i, 1, n) cin >> v[i] >> w[i];
dp[0] = 0;//初始条件
F(i, 1, n) F(j, w[i], b) if(dp[j - w[i]] != INF) dp[j] = min(dp[j], dp[j - w[i]] + v[i]);
if(dp[b] == INF) puts("This is impossible.");
else
cout << "The minimum amount of money in the piggy-bank is " << dp[b] << "." << endl;
}
return 0;
}
hdu 2159
思路:dp[i][j]表杀i只怪,消耗j耐久值能获得的最大经验值
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <sstream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <iomanip>
#include <stack>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int N = 1e3 + 100;
const int MOD = 1e9 + 9;
#define lson l, m, rt << 14
#define rson m + 1, r, rt << 1 | 1
#define F(i, l, r) for(int i = l;i <= (r);++i)
#define RF(i, l, r) for(int i = l;i >= (r);--i)
int dp[N][N], v[N], w[N];
int main()
{
int n, m, k ,s;
while(cin >> n >> m >> k >> s)
{
F(i, 1, k) cin >> v[i] >> w[i];
memset(dp, 0, sizeof(dp));
F(i, 1, k) F(j, 1, s) F(z, w[i], m) dp[j][z] = max(dp[j][z], dp[j - 1][z - w[i]] + v[i]);
bool flag = 1;
for(int i = 1;i <= m && flag;++i)
for(int j = 1;j <= s && flag;++j)
if(dp[j][i] >= n) {flag = 0;cout << m - i << endl;}
if(flag) puts("-1");
}
return 0;
}
POJ 3181
题意:问用1到k里面的数,组成n一共有多少种方案
思路:简单完全背包,但是输入n=1000,k=100时爆long long,根据计算n!大数思想,把一个大数拆成两部分即可
LL dp[N][5];
int main()
{
LL n, k;
LL p = 1e17;
while(cin >> n >> k)
{
if(n == 0)
{
puts("0");
continue;
}
dp[0][0] = 1;
for(int i = 1;i <= k;++i)
for(int j = i;j <= n;++j)
{
dp[j][1] = dp[j][1]+dp[j-i][1]+(dp[j][0]+dp[j-i][0])/p;
dp[j][0] = (dp[j][0]+dp[j-i][0])%p;
}
if(dp[n][1]) cout << dp[n][1];
cout << dp[n][0] << endl;
}
return 0;
}
以后再补题