1. POJ 3616 Milking Time
题目链接:
http://poj.org/problem?id=3616
先按时间先后顺序排序,然后按照题目所要求的规则进行dp。
代码如下:
//include <bits/stdc++.h>
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <stack>
#include <time.h>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll MOD = 1000000007;
const int maxn = 1e3+5;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
template <class T>
inline bool scan_d(T &ret) {
char c; int sgn;
if (c = getchar(), c == EOF) return 0;
while (c != '-' && (c<'0' || c>'9')) c = getchar();
sgn = (c == '-') ? -1 : 1;
ret = (c == '-') ? 0 : (c - '0');
while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
ret *= sgn;
return 1;
}
struct node
{
int st,en,eff;
};
int n,m,r;
node a[maxn];
int dp[maxn];
int compare (node a ,node b)
{
if(a.st!=b.st) return a.st<b.st;
return a.en<b.en;
}
int main()
{
while(scanf("%d%d%d",&n,&m,&r)!=EOF)
{
int ans=0;
for (int i=1;i<=m;i++)
{
scanf("%d%d%d",&a[i].st,&a[i].en,&a[i].eff);
}
a[0].st=a[0].en=a[0].eff=0;
sort (a+1,a+m+1,compare);
memset (dp,0,sizeof(dp));
for (int i=1;i<=m;i++) dp[i]=a[i].eff;
for (int i=1;i<=m;i++)
{
for (int j=1;j<i;j++)
{
if(a[i].st<a[j].en+r) continue;
dp[i]=max(dp[i],dp[j]+a[i].eff);
ans=max(dp[i],ans);
}
}
printf("%d\n",ans);
}
return 0;
}
2. POJ 3486 Computers
题目链接:
http://poj.org/problem?id=3486
思路:
设dp[i]表示为第i天的最小花费,则有dp[i]=min(dp[i],dp[j]+c+a[j+1][i])(0<j<i);
代码如下:
//include <bits/stdc++.h>
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <stack>
#include <time.h>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll MOD = 1000000007;
const int maxn = 1e3+5;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
template <class T>
inline bool scan_d(T &ret) {
char c; int sgn;
if (c = getchar(), c == EOF) return 0;
while (c != '-' && (c<'0' || c>'9')) c = getchar();
sgn = (c == '-') ? -1 : 1;
ret = (c == '-') ? 0 : (c - '0');
while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
ret *= sgn;
return 1;
}
int c;
int n;
int a[maxn][maxn];
int dp[maxn];
int main()
{
while(scanf("%d",&c)!=EOF)
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
for (int j=i;j<=n;j++)
{
scanf("%d",&a[i][j]);
}
}
dp[0]=0;
for (int i=1;i<=n;i++) dp[i]=INF;
int ans=INF;
for (int i=1;i<=n;i++)
{
for (int j=0;j<n;j++)
{
dp[i]=min(dp[i],dp[j]+a[j+1][i]+c);
}
}
printf("%d\n",dp[n]);
}
return 0;
}
3. POJ 3404 Bridge over a rough river
题目链接:
http://poj.org/problem?id=3404
思路:
仅仅是贪心第一个与其他的人一起走的想法是不对的,比如1 2 5 10,1,2现在,然后1回来,之后5,10走,2回来,然后1,2这样就不符合贪心思想。
此题可以通过动态规划来做。
因为存在上面所述的状态转移情况,所以递推式为:
dp[i]=min(dp[i-1]+a[1]+a[i],dp[i-2]+a[1]+a[i]+2*a[2]);
代码如下:
//include <bits/stdc++.h>
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <stack>
#include <time.h>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll MOD = 1000000007;
const int maxn = 50+5;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
template <class T>
inline bool scan_d(T &ret) {
char c; int sgn;
if (c = getchar(), c == EOF) return 0;
while (c != '-' && (c<'0' || c>'9')) c = getchar();
sgn = (c == '-') ? -1 : 1;
ret = (c == '-') ? 0 : (c - '0');
while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
ret *= sgn;
return 1;
}
int n;
int a[maxn];
int dp[maxn];
int main()
{
while(scanf("%d",&n)!=EOF)
{
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
sort(a+1,a+n+1);
dp[0]=0;
dp[1]=a[1];
dp[2]=a[2];
for (int i=3;i<=n;i++)
{
dp[i]=min(dp[i-1]+a[1]+a[i],dp[i-2]+a[1]+a[i]+2*a[2]);
}
printf("%d\n",dp[n]);
}
return 0;
}
4. POJ 1700 Crossing River
题目链接:
http://poj.org/problem?id=1700
此题只是在上一题的基础上加大了数据规模
代码如下:
//include <bits/stdc++.h>
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <stack>
#include <time.h>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll MOD = 1000000007;
const int maxn = 1050+5;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
template <class T>
inline bool scan_d(T &ret) {
char c; int sgn;
if (c = getchar(), c == EOF) return 0;
while (c != '-' && (c<'0' || c>'9')) c = getchar();
sgn = (c == '-') ? -1 : 1;
ret = (c == '-') ? 0 : (c - '0');
while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
ret *= sgn;
return 1;
}
int t;
int n;
int a[maxn];
int dp[maxn];
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
sort(a+1,a+n+1);
dp[0]=0;
dp[1]=a[1];
dp[2]=a[2];
for (int i=3;i<=n;i++)
{
dp[i]=min(dp[i-1]+a[1]+a[i],dp[i-2]+a[1]+a[i]+2*a[2]);
}
printf("%d\n",dp[n]);
}
return 0;
}